Jondlm
Jondlm

Reputation: 8892

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!

Upvotes: 1

Views: 200

Answers (2)

Fernando Flores
Fernando Flores

Reputation: 53

That is the default behavior. If you want to prevent that and get an error, you should type the destructuring:

const { letter = 1 } : IFoo = foo; // "IFoo" added, this should show the error: Type '1' is not assignable to type '"a" | "b" | "c"'

Upvotes: 0

SpencerPark
SpencerPark

Reputation: 3506

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.

Upvotes: 2

Related Questions