Reputation: 8467
I have the following code:
export enum Side {
Left = 'left',
Right = 'right'
}
export interface Crosser {
side: Side
}
export const crossersOnCorrectSide = function(crossers: Crosser[], correctSide: Side): Crosser|undefined {
return crossers.find(crosser => { return crosser.side !== correctSide } )
}
The problem is - I don't want the return type to be Crosser|undefined
, rather I'd like the return type to be the type of the class that is implementing Crosser
or undefined
.
I tried using generics and performing a type assertion:
export const crossersOnCorrectSide = function<T>(crossers: Crosser[], correctSide: Side): T|undefined {
let result = crossers.find(crosser => { return crosser.side !== correctSide } )
if(result !== undefined) {
return result as T
}
return result
//return crossers.find(crosser => { return crosser.side !== correctSide } )
}
but I got "Type Crosser cannot be converted to type T".
Is there any "correct" way of doing this, or will I be forced to use ts-ignore
, or worse, is this bad design and should I just perform the type assertion after recieving the output of crossersOnCorrectSide
?
Upvotes: 2
Views: 2873
Reputation: 677
Given the caller is already using the implementing type, you can just use that type directly:
export const crossersOnCorrectSide = function <T extends Crosser>(crossers: T[], correctSide: Side): T | undefined {
let result = crossers.find(crosser => { return crosser.side !== correctSide } )
if(result !== undefined) {
return result
}
else return undefined
}
It is common to use generics to ensure the right return type without the caller having to perform a cast. However, you'll still need to know the correct type to use for T
when calling the function. It doesn't make any sense for your function to try and detect the actual underlying class.
Upvotes: 1