Filter undefined only in binding patterns in params (#38116)
initialiser. But this is only correct when the initialiser is for a parameter. For example: ```ts declare let x: { s: string } | undefined; const { s } = x; ``` This PR removes undefined from the type of a binding pattern only when the binding pattern's parent is a parameter. This fixes the regression from 3.8. However, it's still not the ideal fix; we should be able to use control flow to solve this problem. Consider: ```ts const { s }: { s: string } | undefined = { s: 'hi' } declare function f({ s }: { s: string } | undefined = { s: 'hi' }): void ``` Neither line should have an error, but the first does in 3.8 and after this change.
This commit is contained in:
parent
d2016912b5
commit
f248567dab
|
@ -7306,7 +7306,7 @@ namespace ts {
|
|||
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) {
|
||||
else if (strictNullChecks && pattern.parent.initializer && isParameter(pattern.parent)) {
|
||||
parentType = getTypeWithFacts(parentType, TypeFacts.NEUndefined);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts(7,9): error TS2339: Property 's' does not exist on type '{ s: string; } | undefined'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts (1 errors) ====
|
||||
const fInferred = ({ a = 0 } = {}) => a;
|
||||
// const fInferred: ({ a }?: { a?: number; }) => number
|
||||
|
||||
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
|
||||
|
||||
declare var t: { s: string } | undefined;
|
||||
const { s } = t;
|
||||
~
|
||||
!!! error TS2339: Property 's' does not exist on type '{ s: string; } | undefined'.
|
||||
|
|
@ -2,7 +2,11 @@
|
|||
const fInferred = ({ a = 0 } = {}) => a;
|
||||
// const fInferred: ({ a }?: { a?: number; }) => number
|
||||
|
||||
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
|
||||
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
|
||||
|
||||
declare var t: { s: string } | undefined;
|
||||
const { s } = t;
|
||||
|
||||
|
||||
//// [contextualTypeForInitalizedVariablesFiltersUndefined.js]
|
||||
"use strict";
|
||||
|
@ -15,3 +19,4 @@ var fAnnotated = function (_a) {
|
|||
var _b = (_a === void 0 ? {} : _a).a, a = _b === void 0 ? 0 : _b;
|
||||
return a;
|
||||
};
|
||||
var s = t.s;
|
||||
|
|
|
@ -12,3 +12,11 @@ const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
|
|||
>a : Symbol(a, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 3, 39))
|
||||
>a : Symbol(a, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 3, 39))
|
||||
|
||||
declare var t: { s: string } | undefined;
|
||||
>t : Symbol(t, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 5, 11))
|
||||
>s : Symbol(s, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 5, 16))
|
||||
|
||||
const { s } = t;
|
||||
>s : Symbol(s, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 6, 7))
|
||||
>t : Symbol(t, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 5, 11))
|
||||
|
||||
|
|
|
@ -18,3 +18,11 @@ const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
|
|||
>{} : {}
|
||||
>a : number
|
||||
|
||||
declare var t: { s: string } | undefined;
|
||||
>t : { s: string; } | undefined
|
||||
>s : string
|
||||
|
||||
const { s } = t;
|
||||
>s : any
|
||||
>t : { s: string; } | undefined
|
||||
|
||||
|
|
|
@ -2,4 +2,7 @@
|
|||
const fInferred = ({ a = 0 } = {}) => a;
|
||||
// const fInferred: ({ a }?: { a?: number; }) => number
|
||||
|
||||
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
|
||||
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
|
||||
|
||||
declare var t: { s: string } | undefined;
|
||||
const { s } = t;
|
||||
|
|
Loading…
Reference in a new issue