Skip to content

Commit f248567

Browse files
authored
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.
1 parent d201691 commit f248567

6 files changed

+41
-3
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7306,7 +7306,7 @@ namespace ts {
73067306
parentType = getNonNullableType(parentType);
73077307
}
73087308
// Filter `undefined` from the type we check against if the parent has an initializer (which handles the `undefined` case implicitly)
7309-
else if (strictNullChecks && pattern.parent.initializer) {
7309+
else if (strictNullChecks && pattern.parent.initializer && isParameter(pattern.parent)) {
73107310
parentType = getTypeWithFacts(parentType, TypeFacts.NEUndefined);
73117311
}
73127312

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts(7,9): error TS2339: Property 's' does not exist on type '{ s: string; } | undefined'.
2+
3+
4+
==== tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts (1 errors) ====
5+
const fInferred = ({ a = 0 } = {}) => a;
6+
// const fInferred: ({ a }?: { a?: number; }) => number
7+
8+
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
9+
10+
declare var t: { s: string } | undefined;
11+
const { s } = t;
12+
~
13+
!!! error TS2339: Property 's' does not exist on type '{ s: string; } | undefined'.
14+

tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
const fInferred = ({ a = 0 } = {}) => a;
33
// const fInferred: ({ a }?: { a?: number; }) => number
44

5-
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
5+
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
6+
7+
declare var t: { s: string } | undefined;
8+
const { s } = t;
9+
610

711
//// [contextualTypeForInitalizedVariablesFiltersUndefined.js]
812
"use strict";
@@ -15,3 +19,4 @@ var fAnnotated = function (_a) {
1519
var _b = (_a === void 0 ? {} : _a).a, a = _b === void 0 ? 0 : _b;
1620
return a;
1721
};
22+
var s = t.s;

tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.symbols

+8
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,11 @@ const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
1212
>a : Symbol(a, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 3, 39))
1313
>a : Symbol(a, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 3, 39))
1414

15+
declare var t: { s: string } | undefined;
16+
>t : Symbol(t, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 5, 11))
17+
>s : Symbol(s, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 5, 16))
18+
19+
const { s } = t;
20+
>s : Symbol(s, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 6, 7))
21+
>t : Symbol(t, Decl(contextualTypeForInitalizedVariablesFiltersUndefined.ts, 5, 11))
22+

tests/baselines/reference/contextualTypeForInitalizedVariablesFiltersUndefined.types

+8
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,11 @@ const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
1818
>{} : {}
1919
>a : number
2020

21+
declare var t: { s: string } | undefined;
22+
>t : { s: string; } | undefined
23+
>s : string
24+
25+
const { s } = t;
26+
>s : any
27+
>t : { s: string; } | undefined
28+

tests/cases/compiler/contextualTypeForInitalizedVariablesFiltersUndefined.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22
const fInferred = ({ a = 0 } = {}) => a;
33
// const fInferred: ({ a }?: { a?: number; }) => number
44

5-
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
5+
const fAnnotated: typeof fInferred = ({ a = 0 } = {}) => a;
6+
7+
declare var t: { s: string } | undefined;
8+
const { s } = t;

0 commit comments

Comments
 (0)