Arihant
Arihant

Reputation: 497

Typescript: Make Generic Typed Parameter Flow From Function to Function

Consider the following code ( also on TS Play )


interface Props<Item> {
    selectedItem?: Item
}

function makeReturn(props: Props) { // complaints : Generic type 'Props<Item>' requires 1 type argument(s).
    if (props.selectedItem) {
        return props.selectedItem
    }

    return ''
}

function useAutosuggest<Item>(
    userProps: Props<Item> = {}
) {
    const retVal = makeReturn(userProps);
    return retVal;
}

interface MyItem {
    city: 'string',
    rating: number
}

const selectedItem = useAutosuggest<MyItem>()

My thought process is – what do I do, so that the makeReturn function be able to know that selectedItem should be of whatever type useAutosuggest takes in (in this case MyType). I'm not sure if I'm thinking correctly. If I am, what to do to act upon this thought process, if not what am I thinking wrong?

Upvotes: 0

Views: 49

Answers (1)

Andrew E
Andrew E

Reputation: 8317

The main things you're looking for is function generics and return types, but there's a couple other things that will help.

First, I recommend using "T" instead of Item. You don't have to, but it's conventional, and it makes it clearer to read in this case (I kept wondering "where is the Item type!):

interface Props<T> {
    selectedItem?: T
}

To your main question, you needed to make the function generic:

function makeReturn<T>(props: Props<T>): T|undefined {
    if (props.selectedItem) {
        return props.selectedItem
    }

    return undefined
}

or technically this is fine too (assuming props is never null or undefined):

function makeReturn<T>(props: Props<T>): T|undefined {
    return props.selectedItem
}

Note how the return type is T|undefined. In your example you returned an empty string. You can't do that in TypeScript without a warning or an error.

I tweaked the next function a bit (but there are multiple ways to skin the cat):

function use<T>(userProps?: Props<T>): T|undefined {
    return makeReturn(userProps || {})
}

Full code (playground):

interface Props<T> {
    selectedItem?: T
}

function makeReturn<T>(props: Props<T>): T|undefined {
    if (props.selectedItem) {
        return props.selectedItem
    }

    return undefined
}

function use<T>(userProps?: Props<T>): T|undefined {
    return makeReturn(userProps || {})
}

interface MyItem {
    city: 'string',
    rating: number
}

const selectedItem = use<MyItem>()

Upvotes: 1

Related Questions