diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e681159faa1..ffc8e886526 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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) { diff --git a/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.js b/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.js new file mode 100644 index 00000000000..9c2a6eaa780 --- /dev/null +++ b/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.js @@ -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; +}; diff --git a/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.symbols b/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.symbols new file mode 100644 index 00000000000..7b675719012 --- /dev/null +++ b/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.symbols @@ -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)) + diff --git a/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.types b/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.types new file mode 100644 index 00000000000..d8278124ff0 --- /dev/null +++ b/tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.types @@ -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 + diff --git a/tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts b/tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts new file mode 100644 index 00000000000..268544f8192 --- /dev/null +++ b/tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts @@ -0,0 +1,5 @@ +// @strict: true +const fInferred = ({ a = 0 } = {}) => a; +// const fInferred: ({ a }?: { a?: number; }) => number + +const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a; \ No newline at end of file