hally9k
hally9k

Reputation: 2583

Why don't discriminated unions in typescript work in this way?

Why can't typescript discriminate based on a common property like this? After reading the docs I thought this would work.

Heres a typescript playground

type Mammal = { legs: number }
type Fish = { fins: number }

type Action1 = {
    type: 'a',
    payload: Mammal 
}


type Action2 = {
    type: 'b',
    payload: Fish
}

type ActionUnion = Action1 | Action2

const A: Action1 = { type: 'a', payload: { legs: 4 } }
const B: Action2 = { type: 'b', payload: { fins: 3 } }

function foo(action: ActionUnion) {
    switch (action.type) {
        case 'a':
            const { legs } = action.payload

        case 'b':
            const { fins } = action.payload

        default:
            break
    } 
}

Upvotes: 1

Views: 53

Answers (2)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249646

They do work like that, but your switch case was falling through to the next case, add a break and it will work

type Mammal = { legs: number }
type Fish = { fins: number }

type Action1 = {
    type: 'a',
    payload: Mammal 
}


type Action2 = {
    type: 'b',
    payload: Fish
}

type ActionUnion = Action1 | Action2

const A: Action1 = { type: 'a', payload: { legs: 4 } }
const B: Action2 = { type: 'b', payload: { fins: 3 } }

function foo(action: ActionUnion) {
    switch (action.type) {
        case 'a':
            const { legs } = action.payload
            break;
        case 'b':
            const { fins } = action.payload
            break;
        default:
            break
    } 
}

Upvotes: 2

Murat Karagöz
Murat Karagöz

Reputation: 37594

You forgot to break your case statement. Should look like this

case 'a':
    const { legs } = action.payload
    break;
case 'b':
    const { fins } = action.payload

Upvotes: 7

Related Questions