typescriptdefaultdestructuring

TypeScript type modification when using defaults and object destructuring assignment


I ran into a strange case today using TypeScript (v3.5.1) that's left me puzzled. I defined an interface with an optional property but TypeScript allowed me to set the default to whatever I want when using object destructuring:

interface IFoo {
    letter?: "a" | "b" | "c";
}

const foo: IFoo = {};

const { letter = 1 } = foo;

console.log(letter); // --> 1
                     // Type signature of `letter`: "a" | "b" | "c" | 1
                     // Why does TS modify the type to include 1?

Run this code in the TypeScript playground.

Using some type inspection I noticed that TypeScript is modifying the expected signature of "a" | "b" | "c" to "a" | "b" | "c" | 1. I was expecting to get a type error when I tried to default letter to 1. Am I missing something here? Thanks!


Solution

  • The destructuring statement is introducing a new variable. It doesn't yet have a type unless one is assigned or in this case inferred.

    Looking at the downcompiled code this becomes even more apparent:

    // const { letter = 1 } = foo;
    var _a = foo.letter, letter = _a === void 0 ? 1 : _a;
    

    Or to clean it up a bit:

    const letter = foo.letter === undefined ? 1 : foo.letter;
    

    letter is either foo.letter or 1 if the former is undefined.