Vladyslav Tymoshchyk
Vladyslav Tymoshchyk

Reputation: 23

Is it possible to make TypeScript understand argument type when function has overloads?

I have the following function with two overloads. The overloads work fine when I'm calling the function, but inside the function body, the type of the second argument is not narrowed based on the value of the first argument.

function foo(event: 'one', value: string): void;
function foo(event: 'two', value: number): void;
function foo(event: 'one' | 'two', value: string | number): void {
    event // 'one' | 'two'
    value // string | number
    if (event === 'one') {
        event // 'one'
        value // !!! string | number , Why not string??
    } else {
        event // 'two'
        value // !!! string | number , Why not number??
    }
}

Is it possible to have type of value - string when first argument is 'one', and of type number when first argument is 'two'?

Upvotes: 1

Views: 54

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249506

Yes it is if you use a union opf tuples in rest parameters and destructure the tuple right in the parameters. In fact using this you don't even need the overloads anymore, the tuple union will be preseneted as overloads:

function foo(...[event, value]: 
  | [event: 'one', value: string]
  | [event: 'two', value: number]): void {
    event // 'one' | 'two'
    value // string | number
    if (event === 'one') {
        event // 'one'
        value // string
    } else {
        event // 'two'
        value // number
    }
}

Playground Link

Limitations: only works if the tuple union is a discriminated union (yours is).

Upvotes: 1

Related Questions