Filter the type of a binding pattern to not include undefined is the pattern parent has an initializer (#37309)

This commit is contained in:
Wesley Wigham 2020-03-12 17:50:05 -07:00 committed by GitHub
parent e0f6ecd957
commit df523b30cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 0 deletions

View File

@ -7164,6 +7164,10 @@ namespace ts {
if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) {
parentType = getNonNullableType(parentType);
}
// Filter `undefined` from the type we check against if the parent has an initializer (which handles the `undefined` case implicitly)
else if (strictNullChecks && pattern.parent.initializer) {
parentType = getTypeWithFacts(parentType, TypeFacts.NEUndefined);
}
let type: Type | undefined;
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {

View File

@ -0,0 +1,17 @@
//// [contextualTypeForInitalizedVariablesFiltersUndefined.ts]
const fInferred = ({ a = 0 } = {}) => a;
// const fInferred: ({ a }?: { a?: number; }) => number
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
//// [contextualTypeForInitalizedVariablesFiltersUndefined.js]
"use strict";
var fInferred = function (_a) {
var _b = (_a === void 0 ? {} : _a).a, a = _b === void 0 ? 0 : _b;
return a;
};
// const fInferred: ({ a }?: { a?: number; }) => number
var fAnnotated = function (_a) {
var _b = (_a === void 0 ? {} : _a).a, a = _b === void 0 ? 0 : _b;
return a;
};

View File

@ -0,0 +1,14 @@
=== tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts ===
const fInferred = ({ a = 0 } = {}) => a;
>fInferred : Symbol(fInferred, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 0, 5))
>a : Symbol(a, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 0, 20))
>a : Symbol(a, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 0, 20))
// const fInferred: ({ a }?: { a?: number; }) => number
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
>fAnnotated : Symbol(fAnnotated, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 3, 5))
>fInferred : Symbol(fInferred, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 0, 5))
>a : Symbol(a, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 3, 39))
>a : Symbol(a, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 3, 39))

View File

@ -0,0 +1,20 @@
=== tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts ===
const fInferred = ({ a = 0 } = {}) => a;
>fInferred : ({ a }?: { a?: number | undefined; }) => number
>({ a = 0 } = {}) => a : ({ a }?: { a?: number | undefined; }) => number
>a : number
>0 : 0
>{} : { a?: number | undefined; }
>a : number
// const fInferred: ({ a }?: { a?: number; }) => number
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
>fAnnotated : ({ a }?: { a?: number | undefined; }) => number
>fInferred : ({ a }?: { a?: number | undefined; }) => number
>({ a = 0 } = {}) => a : ({ a }?: { a?: number | undefined; } | undefined) => number
>a : number
>0 : 0
>{} : {}
>a : number

View File

@ -0,0 +1,5 @@
// @strict: true
const fInferred = ({ a = 0 } = {}) => a;
// const fInferred: ({ a }?: { a?: number; }) => number
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;