0

Generic interface

export interface BaseService {
   getById<T extends number | string>(id: T): Promise<SomeType>;
}

And, the implementation

export class AService implements BaseService {
    async getById(id: number): Promise<SomeType> {
       // logic
    }

    //Other functions will be implemented here
}

And, the error I am getting:

Property 'getById' in type 'AService' is not assignable to the same property in base 
type 'BaseService'.
Type '(id: number) => Promise<SomeType>' is not assignable to type '<T extends 
string | number>(id: T) => Promise<SomeType>'.
Types of parameters 'id' and 'id' are incompatible.
  Type 'T' is not assignable to type 'number'.
    Type 'string | number' is not assignable to type 'number'.
      Type 'string' is not assignable to type 'number'.ts(2416)

Couple of things that I have tried:

getById<T extends number>(id: T): Promise<SomeType>; //This works, But I would have some methods with id type string

And,

getById<T>(id: T): Promise<SomeType>; //still compains

I have been following Documentation. But, haven't encountered any similar thing.

Would really appreciate any ideas or thoughts or any documentation!!

6
  • Why are these methods generic? You don't use the generic type parameter at all, which means they don't need to be generic at all. For example: tsplay.dev/wgAnlm Commented Jan 28, 2023 at 20:34
  • Please edit the code to be a self-contained minimal reproducible example that demonstrates your issue without unrelated problems when pasted, as-is, into a standalone IDE. For example, errors because BaseEntity or SpeciesEntity are undefined, should be removed. Commented Jan 28, 2023 at 20:36
  • @AlexWayne, I am using the id: T which is generic. and Id could be another type Commented Jan 28, 2023 at 20:40
  • The generic type parameter in getById<T extends number | string>(id: T) let's you capture a type used for the argument id and use that type somewhere else, such as the return type of the method. But your return types do not depend on T at all. If you don't use T anywhere else, then you don't need it, and you're better off using the constraint as the argument type directly. Commented Jan 28, 2023 at 20:47
  • 1
    Type arguments for generic functions/methods are chosen by the caller, not the implementer. If you have a value s of type BaseService (or any type that extends it), then you are allowed to call s.getById("hello") and T will be inferred as "hello". The implementer of getById() does not get to decide that T will be number or anything else. It seems you want BaseService itself to be generic in the type of id, like this; does that meet your needs? If so I could write up an answer; if not, what am I missing? Commented Jan 28, 2023 at 20:48

1 Answer 1

2

The getById<T extends number | string>(id: T): Promise<SomeType> generic method is pretty pointless, that's more or less equivalent to just declaring a method of type getById(id: number | string): Promise<SomeType>.

I suspect what you actually want is

export interface BaseService<T extends number | string> {
    getById(id: T): Promise<SomeType>;
}
export class AService implements BaseService<number> {
//                                          ^^^^^^^^
    async getById(id: number): Promise<SomeType> {
        …
    }
    …
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is an answer. But I have a function that returns service based on a string and because of that I cant have BaseService<T> and Different service could have different T.
You can't, and shouldn't, have a function that returns a service without telling the caller whether it will be a service accepting a number or accepting a string (or both). You can declare it to return a BaseService<never> (and then return different services), but that won't be particularly useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.