Home > Net >  Why Typescript cannot infer discriminated types when destructing
Why Typescript cannot infer discriminated types when destructing

Time:08-06

I try in vain to narrow discriminated types with object destructuring. I thought Typescript is able to infer them since v4.4.

However, I cannot do it in this code (just an example of idea):

type WritableRecord = {
    someField: 'a'
}

type ReadonlyRecord = {
    otherField: 'b'
}

type Writable = {
    readonly: false;
} & WritableRecord;

type Readonly = {
    readonly: true;
} & ReadonlyRecord;

export type RecordProps = Readonly | Writable

type Fn = (props: RecordProps) => void

const fn: Fn = ({ readonly, ...props }) => {
    switch (readonly) {
        case true:
            const readonlyCheck: ReadonlyRecord = props

            break;
        case false:
            const writableCheck: WritableRecord = props
            break
    }
}

But without destructuring it works:

type WritableRecord = {
    someField: 'a'
}

type ReadonlyRecord = {
    otherField: 'b'
}

type Writable = {
    readonly: false;
} & WritableRecord;

type Readonly = {
    readonly: true;
} & ReadonlyRecord;

export type RecordProps = Readonly | Writable

type Fn = (props: RecordProps) => void

const fn: Fn = (props) => {
    switch (props.readonly) {
        case true:
            {
                const { readonly, ...readonlyProps } = props
                const readonlyCheck: ReadonlyRecord = readonlyProps
                break;
            }


        case false:
            {
                const { readonly, ...writableProps } = props
                const writableCheck: WritableRecord = writableProps
                break;
            }
    }
}

Maybe, I get v4.4 announcement wrong, or is there an error?

CodePudding user response:

You've just discovered that currently (as of TS4.7) there's no support for control flow analysis for destructured rest elements. This is a known missing feature of TypeScript, requested at microsoft/TypeScript#46680.

If you want to see this supported you might want to go to that issue and give it a

  • Related