Nick
Nick

Reputation: 16576

Optional generic parameter type narrowing

I have the following function that takes an optional argument of type T (a generic).

function test<T>(foo?: T) {
  return foo;
}

const result = test("bar");
// result is type "bar" | undefined

const result2 = test();
// result2 is type "unknown"

How can I correctly type this function such that the compiler will be able to tell that the result variable is of type "bar" and not type "bar" | undefined and additionally the result2 variable is of type undefined and not type unknown?

Upvotes: 1

Views: 214

Answers (3)

kaya3
kaya3

Reputation: 51053

You can use overload signatures to achieve this:

function test(): undefined;
function test<T>(foo: T): T;
function test<T>(foo?: T) {
  return foo;
}

const result = test("bar");
// result is type "bar"

const result2 = test();
// result2 is type undefined

Playground Link

Upvotes: 1

Nicholas Tower
Nicholas Tower

Reputation: 85012

I would do this with function overloading:

function test<T>(foo: T): T;
function test<T>(foo?: undefined): undefined;
function test<T>(foo?: T): T | undefined {
    return foo;
}

const result = test("bar"); // result is of type "bar"

const result2 = test(); //result2 is of type undefined

Playground link

Upvotes: 2

shadowtime2000
shadowtime2000

Reputation: 118

The reason it is "bar" | undefined is because you are setting foo to an optional parameter. Optional parameters are the same as undefined in JS so using foo?: T will automatically append a | undefined to the type.

Upvotes: 0

Related Questions