Struggling to create a single generic function that can return child interfaces inheriting the same parent interface.
Specifically, looking to implement the getById
method:
interface Car { brand: string }
interface Ford extends Car { someUniqueAttribute: string }
interface Ferrari extends Car { someOtherUniqueAttribute: string }
const aFord: Ford = getById<Ford>('1')
const aFerrari: Ferrari = getById<Ferrari>('2')
Tried two approaches:
Using generic
:
interface CarRepository {
getById<C extends Car>(id : string): C
}
class CarRepositoryImpl implements CarRepository {
public getById<C extends Car> (id: string): C {
return id === '1'
? { brand: 'Ford', someUniqueAttribute: 'foo' }
: { brand: 'Ferrari', someOtherUniqueAttribute: 'bar' }
}
}
Encountered the error:
TS2322: Type '{ brand: string; }' is not assignable to type 'C'.
'{ brand: string; }' is assignable to the constraint of type 'C', but 'C' could be instantiated with a different subtype of constraint 'Car'
Using method overloads
:
interface CarRepository {
getById(id : string): Ford
getById(id : string): Ferrari
}
class CarRepositoryImpl implements CarRepository {
public getById (id: string): Ford | Ferrari {
return id === '1'
? { brand: 'Ford', someUniqueAttribute: 'foo' }
: { brand: 'Ferrari', someOtherUniqueAttribute: 'bar' }
}
}
Resulted in the error:
Property 'getById' in type 'CarRepositoryImpl' is not assignable to the same property in base type 'CarRepository'.
Type '(id: string) => Ford | Ferrari' is not assignable to type '{ (id: string): Ford; (id: string): Ferrari; }'.
Type 'Ford | Ferrari' is not assignable to type 'Ford'.
Property 'someUniqueAttribute' is missing in type 'Ferrari' but required in type 'Ford'.(2416)
Even though I comprehend the issue with TypeScript, struggling to find the right implementation. Is there a way to accomplish this in TypeScript?