Foobar
Foobar

Reputation: 8467

Typescript - Make the function return type the class that an interface implements

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

Answers (1)

pere57
pere57

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

Related Questions