Skip to content

How to make one type depends on argument

Is it possible to make return type of function dependent on the argument type?

const exampleFunction<T> = (initial?: T, ...anotherArgs) => { ...Some logic }

In this example by default we can use T | undefined, but I need that return type of function always be T if initial data is defined and (T | undefined) if it is undefined

Answer

Is it possible to make return type of function dependent on the argument type?

This question in a general sense is typically answered by function overloads.

In this case you could do something like:

function exampleFunction<T>(initial: T): T // overload 1
function exampleFunction(initial?: undefined): undefined // overload 2

// Implementation
function exampleFunction<T>(initial?: T): T | undefined {
    return initial
}

const a: { abc: number } = exampleFunction({ abc: 123 }) // use overload 1

const b: undefined = exampleFunction() // use overload 2
const c: undefined = exampleFunction(undefined) // use overload 2

Playground


However, reading your question more carefully…

always be T if initial data is defined and (T | undefined) if it is undefined

You can change the second overload to:

function exampleFunction<T>(initial?: undefined): T | undefined // overload 2

But that will require a manual type for T since none can be inferred.

const b: { def: string } | undefined = exampleFunction<{ def: string }>() // use overload 2

Playground