TypeScript: How to write a function with conditional return type

Here is another solution which works great as well.

I like this solution better than the accepted answer because you will get correct type deduction when coding:

enter image description here

You can see when hovering, it correctly deduced the type.

Here is the code from the screenshot:

export type Name = { name: string }
export type Id = { id: number }
export type Value<T extends string | number> = T extends string ? Name : Id

export function create<T extends string | number>(value: T): Value<T> {
    if (typeof value === 'string') return { name: value } as unknown as Value<T>

    return { id: value } as unknown as Value<T>
}

The problem is inside the function T is not known, so you can't really assign a value to Value<T>. One option would be to use a type assertion. A more type safe option would be to use a separate implementation signature, that would be more relaxed about the input and output type:

export function create<T extends string | number>(value: T): Value<T> // public signature
export function create(value: string | number): Name | Id { // more relaxed private implementation signature 
    if (typeof value === "string") return { name: value }

    return { id: value }
}

Tags:

Typescript