Volodymyr Lapan
Volodymyr Lapan

Reputation: 101

How to get discriminated union behavior with overloading

I have function overloading

function MyFunc(values: IFirst, type: MyEnum.FIRST): number
function MyFunc(values: ISecond, type: MyEnum.SECOND): number
function MyFunc(values: (IFirst | ISecond), type: (MyEnum.FIRST | MyEnum.SECOND)): number {
  if(type === MyEnum.FIRST) {
    values.
  }
  ...
}

Why my values inside if statement is conjunction of IFirst and ISecond ?

How to get discriminated union behavior here? Without adding type string to interfaces, but with type argument.

I want my values to be IFirst in if statement.

Upvotes: 0

Views: 74

Answers (2)

Roberto Zvjerković
Roberto Zvjerković

Reputation: 10157

You could wrap parameters in object, so they can be discriminated:

enum MyEnum {
    FIRST,
    SECOND
}

interface IFirst {
    first: number;
}

interface ISecond {
    second: number;
}

function MyFunc(param: { value: IFirst, type: MyEnum.FIRST }): number
function MyFunc(param: { value: ISecond, type: MyEnum.SECOND }): number
function MyFunc(param: { value: IFirst, type: MyEnum.FIRST } | { value: ISecond, type: MyEnum.SECOND }): number {
    if (param.type === MyEnum.FIRST) {
        return param.value.first;
    } else {
        return param.value.second;
    }
}

Upvotes: 1

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250226

Variables (or parameters) in this case never narrow one another, they can only narrow themselves.

You can get the discriminated union behavior with a tuple, and you can use tuples in rest parameters to spread the tuple to the parameters. The biggest disadvantage of this is you will have to access the tuple items with numbers.

function MyFunc(values: IFirst, type: MyEnum.FIRST): number
function MyFunc(values: ISecond, type: MyEnum.SECOND): number
function MyFunc(...params: [IFirst, MyEnum.FIRST] | [ISecond, MyEnum.SECOND]): number {
  if(params[1] === MyEnum.FIRST) {
      return params[0].first;
  } else {
      return params[0].second;
  }
}

Playground Link

Upvotes: 1

Related Questions