Closed
Description
TypeScript Version: 4.2.0-dev.20201105
Search Terms:
- spread optional
Expected behavior:
The start
symbols should both have type number | undefined
.
Actual behavior:
The one destructured from the conditional spread has somehow dropped the undefined
.
Related Issues:
Code
I'd expect the two start
variables in the following code to have the same type. But they don't, one is number
, whereas the other is number | undefined
:
declare let hasDates: boolean;
{
const nameTitle = { name: 'Khufu', title: 'Pharaoh' };
const pharaoh = {
...nameTitle,
...(hasDates && { start: -2589, end: -2566 }),
};
// type is const pharaoh: {
// start?: number;
// end?: number;
// name: string;
// title: string;
// }, which is character-for-character identical to Reign, below.
const { start } = pharaoh;
// const start: number
}
interface Reign {
start?: number;
end?: number;
name: string;
title: string;
}
declare let reign: Reign;
{
const { start } = reign;
// const start: number | undefined
}
Output
"use strict";
{
const nameTitle = { name: 'Khufu', title: 'Pharaoh' };
const pharaoh = Object.assign(Object.assign({}, nameTitle), (hasDates && { start: -2589, end: -2566 }));
// type is const pharaoh: {
// start?: number;
// end?: number;
// name: string;
// title: string;
// }, which is character-for-character identical to Reign, below.
const { start } = pharaoh;
// const start: number
}
{
const { start } = reign;
// const start: number | undefined
}
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "ES2017",
"jsx": "React",
"module": "ESNext"
}
}
Playground Link: Provided