Skip to content

Commit ec69e2b

Browse files
committed
Always remove undefined from the type arguments at tuples' optional elements
1 parent 64843f4 commit ec69e2b

11 files changed

+64
-19
lines changed

Diff for: src/compiler/checker.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -12862,7 +12862,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1286212862
indexInfos = source.declaredIndexInfos;
1286312863
}
1286412864
else {
12865-
mapper = createTypeMapper(typeParameters, typeArguments);
12865+
mapper = createTypeMapper(
12866+
typeParameters,
12867+
isTupleType(type) ? map(typeArguments, (t, i) => addOptionality(t, /*isProperty*/ true, !!(type.target.elementFlags[i] & ElementFlags.Optional))) : typeArguments
12868+
);
1286612869
members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
1286712870
callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper);
1286812871
constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper);
@@ -15563,7 +15566,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1556315566
const typeArguments = !node ? emptyArray :
1556415567
node.kind === SyntaxKind.TypeReference ? concatenate(type.target.outerTypeParameters, getEffectiveTypeArguments(node, type.target.localTypeParameters!)) :
1556515568
node.kind === SyntaxKind.ArrayType ? [getTypeFromTypeNode(node.elementType)] :
15566-
map(node.elements, element => removeMissingType(getTypeFromTypeNode(element), element.kind === SyntaxKind.OptionalType));
15569+
map(node.elements, element => getTypeFromTypeNode(element.kind === SyntaxKind.OptionalType ? (element as OptionalTypeNode).type : element));
1556715570
if (popTypeResolution()) {
1556815571
type.resolvedTypeArguments = type.mapper ? instantiateTypes(typeArguments, type.mapper) : typeArguments;
1556915572
}
@@ -22723,11 +22726,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2272322726
}
2272422727
}
2272522728

22729+
// TODO: recheck if `addOptionality` shouldn't get called here as well
2272622730
const sourceType = removeMissingType(sourceTypeArguments[sourcePosition], !!(sourceFlags & targetFlags & ElementFlags.Optional));
2272722731
const targetType = targetTypeArguments[targetPosition];
22732+
const isTargetOptional = !!(targetFlags & ElementFlags.Optional);
2272822733

2272922734
const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) :
22730-
removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional));
22735+
removeMissingType(addOptionality(targetType, /*isProperty*/ true, isTargetOptional), isTargetOptional);
2273122736
const related = isRelatedTo(sourceType, targetCheckType, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState);
2273222737
if (!related) {
2273322738
if (reportErrors && (targetArity > 1 || sourceArity > 1)) {

Diff for: tests/baselines/reference/destructuringControlFlow.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ function f4() {
162162
// Repro from #31770
163163

164164
type KeyValue = [string, string?];
165-
>KeyValue : [string, (string | undefined)?]
165+
>KeyValue : [string, string?]
166166

167167
let [key, value]: KeyValue = ["foo"];
168168
>key : string

Diff for: tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).types

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type Item = {
1212
};
1313

1414
type Foo = [Item?];
15-
>Foo : [(Item | undefined)?]
15+
>Foo : [Item?]
1616

1717
declare const foo: Foo;
1818
>foo : Foo

Diff for: tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).types

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type Item = {
1212
};
1313

1414
type Foo = [Item?];
15-
>Foo : [(Item | undefined)?]
15+
>Foo : [Item?]
1616

1717
declare const foo: Foo;
1818
>foo : Foo
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
forOfOptionalTupleMember.ts(12,3): error TS18048: 'item' is possibly 'undefined'.
2+
3+
4+
==== forOfOptionalTupleMember.ts (1 errors) ====
5+
// repro from https://github.com/microsoft/TypeScript/issues/54302
6+
7+
type Item = {
8+
value: string;
9+
};
10+
11+
type Foo = [Item?];
12+
13+
declare const foo: Foo;
14+
15+
for (let item of foo) {
16+
item.value;
17+
~~~~
18+
!!! error TS18048: 'item' is possibly 'undefined'.
19+
}
20+

Diff for: tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=es5).types

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ declare const foo: Foo;
1818
>foo : Foo
1919

2020
for (let item of foo) {
21-
>item : Item
21+
>item : Item | undefined
2222
>foo : Foo
2323

2424
item.value;
2525
>item.value : string
26-
>item : Item
26+
>item : Item | undefined
2727
>value : string
2828
}
2929

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
forOfOptionalTupleMember.ts(12,3): error TS18048: 'item' is possibly 'undefined'.
2+
3+
4+
==== forOfOptionalTupleMember.ts (1 errors) ====
5+
// repro from https://github.com/microsoft/TypeScript/issues/54302
6+
7+
type Item = {
8+
value: string;
9+
};
10+
11+
type Foo = [Item?];
12+
13+
declare const foo: Foo;
14+
15+
for (let item of foo) {
16+
item.value;
17+
~~~~
18+
!!! error TS18048: 'item' is possibly 'undefined'.
19+
}
20+

Diff for: tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=true,target=esnext).types

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ declare const foo: Foo;
1818
>foo : Foo
1919

2020
for (let item of foo) {
21-
>item : Item
21+
>item : Item | undefined
2222
>foo : Foo
2323

2424
item.value;
2525
>item.value : string
26-
>item : Item
26+
>item : Item | undefined
2727
>value : string
2828
}
2929

Diff for: tests/baselines/reference/optionalTupleElements1.types

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ type T1 = [number, string, boolean];
55
>T1 : [number, string, boolean]
66

77
type T2 = [number, string, boolean?];
8-
>T2 : [number, string, (boolean | undefined)?]
8+
>T2 : [number, string, boolean?]
99

1010
type T3 = [number, string?, boolean?];
11-
>T3 : [number, (string | undefined)?, (boolean | undefined)?]
11+
>T3 : [number, string?, boolean?]
1212

1313
type T4 = [number?, string?, boolean?];
14-
>T4 : [(number | undefined)?, (string | undefined)?, (boolean | undefined)?]
14+
>T4 : [number?, string?, boolean?]
1515

1616
type L1 = T1["length"];
1717
>L1 : 3
@@ -26,7 +26,7 @@ type L4 = T4["length"];
2626
>L4 : 0 | 3 | 2 | 1
2727

2828
type T5 = [number, string?, boolean]; // Error
29-
>T5 : [number, (string | undefined)?, boolean]
29+
>T5 : [number, string?, boolean]
3030

3131
function f1(t1: T1, t2: T2, t3: T3, t4: T4) {
3232
>f1 : (t1: T1, t2: T2, t3: T3, t4: T4) => void

Diff for: tests/baselines/reference/restTupleElements1.types

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
=== restTupleElements1.ts ===
44
type T00 = [string?];
5-
>T00 : [(string | undefined)?]
5+
>T00 : [string?]
66

77
type T01 = [string, string?];
8-
>T01 : [string, (string | undefined)?]
8+
>T01 : [string, string?]
99

1010
type T02 = [string?, string]; // Error
11-
>T02 : [(string | undefined)?, string]
11+
>T02 : [string?, string]
1212

1313
type T03 = [...string[]];
1414
>T03 : string[]

Diff for: tests/baselines/reference/variadicTuples2.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ type V10 = [number, ...string[], ...boolean[]]; // Error
1616
>V10 : [number, ...string[], ...boolean[]]
1717

1818
type V11 = [number, ...string[], boolean?]; // Error
19-
>V11 : [number, ...string[], (boolean | undefined)?]
19+
>V11 : [number, ...string[], boolean?]
2020

2121
type V12 = [number, string?, boolean]; // Error
22-
>V12 : [number, (string | undefined)?, boolean]
22+
>V12 : [number, string?, boolean]
2323

2424
// Normalization
2525

0 commit comments

Comments
 (0)