Skip to content

Union type allows incorrect type causing runtime errors #53953

@alesmenzel

Description

@alesmenzel

Bug Report

Defining a function with a parameter that is a union of 2 objects doesn't properly check whether the input is valid.

🔎 Search Terms

function parameter, union type

🕗 Version & Regression Information

⏯ Playground Link

Playground link with relevant code

💻 Code

type A = {
    a: number
}

type B = {
    b: string
    c: boolean
}

function test(param: A | B) {
    if ('b' in param) {
        console.log(param)
        //           ^?
        // Here the type is narrowed to B, but from usage we can see that the property C is missing which could cause runtime error
    }
    // ...
}

test({  a: 42, b: 'foo' })

🙁 Actual behavior

TS doesn't show an error that we are missing property "C" even though it is required by type B. I think the test({ a: 42, b: 'foo' }) usage should only allow one of the types A or B, see below:

test({  a: 42 }) // valid
test({  b: 'foo' }) // invalid, missing c
test({  a: 42, b: 'foo' }) // invalid - either missing c or extra a
test({  a: 42, b: 'foo', c: false }) // invalid - either extra a or extra b/c

Even though TS is a structurally typed language, when using object literals, it checks known keys.

🙂 Expected behavior

Only one of the type A or B is allowed to be passed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions