Skip to content

Commit 31d5bf7

Browse files
committed
Fixed more cases
1 parent cd8f59c commit 31d5bf7

13 files changed

+515
-36
lines changed

src/compiler/checker.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12863,7 +12863,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1286312863
}
1286412864
else {
1286512865
mapper = createTypeMapper(typeParameters, typeArguments);
12866-
members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
12866+
const propertiesMapper = isTupleType(type)
12867+
? createTypeMapper(typeParameters, sameMap(typeArguments, (t, i) => addOptionality(t, /*isProperty*/ true, !!(type.target.elementFlags[i] & ElementFlags.Optional))))
12868+
: mapper;
12869+
members = createInstantiatedSymbolTable(source.declaredProperties, propertiesMapper, /*mappingThisOnly*/ typeParameters.length === 1);
1286712870
callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper);
1286812871
constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper);
1286912872
indexInfos = instantiateIndexInfos(source.declaredIndexInfos, 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 => getTypeFromTypeNode(element.kind === SyntaxKind.OptionalType && exactOptionalPropertyTypes ? (element as OptionalTypeNode).type : element));
15569+
map(node.elements, getTypeFromTypeNode);
1556715570
if (popTypeResolution()) {
1556815571
type.resolvedTypeArguments = type.mapper ? instantiateTypes(typeArguments, type.mapper) : typeArguments;
1556915572
}
@@ -16552,7 +16555,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1655216555
if (flags & (ElementFlags.Optional | ElementFlags.Rest)) {
1655316556
lastOptionalOrRestIndex = expandedFlags.length;
1655416557
}
16555-
expandedTypes.push(flags & ElementFlags.Optional ? addOptionality(type, /*isProperty*/ true) : type);
16558+
expandedTypes.push(flags & ElementFlags.Optional && !exactOptionalPropertyTypes ? addOptionality(type, /*isProperty*/ true) : type);
1655616559
expandedFlags.push(flags);
1655716560
expandedDeclarations.push(declaration);
1655816561
}
@@ -16591,7 +16594,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1659116594
}
1659216595

1659316596
function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type {
16594-
return addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true);
16597+
const type = getTypeFromTypeNode(node.type);
16598+
return exactOptionalPropertyTypes ? type : addOptionality(type, /*isProperty*/ true);
1659516599
}
1659616600

1659716601
function getTypeId(type: Type): TypeId {
@@ -18829,8 +18833,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1882918833

1883018834
function getTypeFromNamedTupleTypeNode(node: NamedTupleMember): Type {
1883118835
const links = getNodeLinks(node);
18832-
return links.resolvedType || (links.resolvedType = node.dotDotDotToken ? getTypeFromRestTypeNode(node) :
18833-
addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true, !!node.questionToken));
18836+
if (links.resolvedType) {
18837+
return links.resolvedType;
18838+
}
18839+
let type: Type;
18840+
if (node.dotDotDotToken) {
18841+
type = getTypeFromRestTypeNode(node);
18842+
}
18843+
else {
18844+
type = getTypeFromTypeNode(node.type);
18845+
if (!exactOptionalPropertyTypes) {
18846+
type = addOptionality(type, /*isProperty*/ true, !!node.questionToken);
18847+
}
18848+
}
18849+
return links.resolvedType = type;
1883418850
}
1883518851

1883618852
function getTypeFromTypeNode(node: TypeNode): Type {
@@ -22723,11 +22739,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2272322739
}
2272422740
}
2272522741

22726-
const sourceType = removeMissingType(sourceTypeArguments[sourcePosition], !!(sourceFlags & targetFlags & ElementFlags.Optional));
22742+
const sourceType = sourceTypeArguments[sourcePosition];
2272722743
const targetType = targetTypeArguments[targetPosition];
22744+
const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType;
2272822745

22729-
const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) :
22730-
removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional));
2273122746
const related = isRelatedTo(sourceType, targetCheckType, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState);
2273222747
if (!related) {
2273322748
if (reportErrors && (targetArity > 1 || sourceArity > 1)) {
Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,45 @@
1-
forOfOptionalTupleMember.ts(12,3): error TS18048: 'item' is possibly 'undefined'.
1+
forOfOptionalTupleMember.ts(10,3): error TS18048: 'item' is possibly 'undefined'.
2+
forOfOptionalTupleMember.ts(16,3): error TS18048: 'item' is possibly 'undefined'.
3+
forOfOptionalTupleMember.ts(21,5): error TS18048: 'num' is possibly 'undefined'.
4+
forOfOptionalTupleMember.ts(27,5): error TS18048: 'num' is possibly 'undefined'.
25

36

4-
==== forOfOptionalTupleMember.ts (1 errors) ====
7+
==== forOfOptionalTupleMember.ts (4 errors) ====
58
// repro from https://github.com/microsoft/TypeScript/issues/54302
69

710
type Item = {
811
value: string;
912
};
1013

1114
type Foo = [Item?];
12-
1315
declare const foo: Foo;
14-
1516
for (let item of foo) {
1617
item.value;
1718
~~~~
1819
!!! error TS18048: 'item' is possibly 'undefined'.
1920
}
21+
22+
type Foo2 = [item?: Item];
23+
declare const foo2: Foo2;
24+
for (let item of foo2) {
25+
item.value;
26+
~~~~
27+
!!! error TS18048: 'item' is possibly 'undefined'.
28+
}
29+
30+
function fn1(t: [number, number?, number?]) {
31+
for (let num of t) {
32+
num.toString()
33+
~~~
34+
!!! error TS18048: 'num' is possibly 'undefined'.
35+
}
36+
}
37+
38+
function fn2(t: [a: number, b?: number, c?: number]) {
39+
for (let num of t) {
40+
num.toString()
41+
~~~
42+
!!! error TS18048: 'num' is possibly 'undefined'.
43+
}
44+
}
2045

tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=es5).symbols

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,64 @@ type Foo = [Item?];
1616
>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0))
1717

1818
declare const foo: Foo;
19-
>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 8, 13))
19+
>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13))
2020
>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2))
2121

2222
for (let item of foo) {
23-
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 10, 8))
24-
>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 8, 13))
23+
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8))
24+
>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13))
2525

2626
item.value;
2727
>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13))
28-
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 10, 8))
28+
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8))
2929
>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13))
3030
}
3131

32+
type Foo2 = [item?: Item];
33+
>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1))
34+
>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0))
35+
36+
declare const foo2: Foo2;
37+
>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13))
38+
>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1))
39+
40+
for (let item of foo2) {
41+
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8))
42+
>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13))
43+
44+
item.value;
45+
>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13))
46+
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8))
47+
>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13))
48+
}
49+
50+
function fn1(t: [number, number?, number?]) {
51+
>fn1 : Symbol(fn1, Decl(forOfOptionalTupleMember.ts, 16, 1))
52+
>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13))
53+
54+
for (let num of t) {
55+
>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10))
56+
>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13))
57+
58+
num.toString()
59+
>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
60+
>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10))
61+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
62+
}
63+
}
64+
65+
function fn2(t: [a: number, b?: number, c?: number]) {
66+
>fn2 : Symbol(fn2, Decl(forOfOptionalTupleMember.ts, 22, 1))
67+
>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13))
68+
69+
for (let num of t) {
70+
>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10))
71+
>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13))
72+
73+
num.toString()
74+
>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
75+
>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10))
76+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
77+
}
78+
}
79+

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,51 @@ for (let item of foo) {
2727
>value : string
2828
}
2929

30+
type Foo2 = [item?: Item];
31+
>Foo2 : [item?: Item | undefined]
32+
33+
declare const foo2: Foo2;
34+
>foo2 : Foo2
35+
36+
for (let item of foo2) {
37+
>item : Item | undefined
38+
>foo2 : Foo2
39+
40+
item.value;
41+
>item.value : string
42+
>item : Item | undefined
43+
>value : string
44+
}
45+
46+
function fn1(t: [number, number?, number?]) {
47+
>fn1 : (t: [number, number?, number?]) => void
48+
>t : [number, (number | undefined)?, (number | undefined)?]
49+
50+
for (let num of t) {
51+
>num : number | undefined
52+
>t : [number, (number | undefined)?, (number | undefined)?]
53+
54+
num.toString()
55+
>num.toString() : string
56+
>num.toString : (radix?: number | undefined) => string
57+
>num : number | undefined
58+
>toString : (radix?: number | undefined) => string
59+
}
60+
}
61+
62+
function fn2(t: [a: number, b?: number, c?: number]) {
63+
>fn2 : (t: [a: number, b?: number, c?: number]) => void
64+
>t : [a: number, b?: number | undefined, c?: number | undefined]
65+
66+
for (let num of t) {
67+
>num : number | undefined
68+
>t : [a: number, b?: number | undefined, c?: number | undefined]
69+
70+
num.toString()
71+
>num.toString() : string
72+
>num.toString : (radix?: number | undefined) => string
73+
>num : number | undefined
74+
>toString : (radix?: number | undefined) => string
75+
}
76+
}
77+
Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,45 @@
1-
forOfOptionalTupleMember.ts(12,3): error TS18048: 'item' is possibly 'undefined'.
1+
forOfOptionalTupleMember.ts(10,3): error TS18048: 'item' is possibly 'undefined'.
2+
forOfOptionalTupleMember.ts(16,3): error TS18048: 'item' is possibly 'undefined'.
3+
forOfOptionalTupleMember.ts(21,5): error TS18048: 'num' is possibly 'undefined'.
4+
forOfOptionalTupleMember.ts(27,5): error TS18048: 'num' is possibly 'undefined'.
25

36

4-
==== forOfOptionalTupleMember.ts (1 errors) ====
7+
==== forOfOptionalTupleMember.ts (4 errors) ====
58
// repro from https://github.com/microsoft/TypeScript/issues/54302
69

710
type Item = {
811
value: string;
912
};
1013

1114
type Foo = [Item?];
12-
1315
declare const foo: Foo;
14-
1516
for (let item of foo) {
1617
item.value;
1718
~~~~
1819
!!! error TS18048: 'item' is possibly 'undefined'.
1920
}
21+
22+
type Foo2 = [item?: Item];
23+
declare const foo2: Foo2;
24+
for (let item of foo2) {
25+
item.value;
26+
~~~~
27+
!!! error TS18048: 'item' is possibly 'undefined'.
28+
}
29+
30+
function fn1(t: [number, number?, number?]) {
31+
for (let num of t) {
32+
num.toString()
33+
~~~
34+
!!! error TS18048: 'num' is possibly 'undefined'.
35+
}
36+
}
37+
38+
function fn2(t: [a: number, b?: number, c?: number]) {
39+
for (let num of t) {
40+
num.toString()
41+
~~~
42+
!!! error TS18048: 'num' is possibly 'undefined'.
43+
}
44+
}
2045

tests/baselines/reference/forOfOptionalTupleMember(exactoptionalpropertytypes=false,target=esnext).symbols

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,64 @@ type Foo = [Item?];
1616
>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0))
1717

1818
declare const foo: Foo;
19-
>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 8, 13))
19+
>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13))
2020
>Foo : Symbol(Foo, Decl(forOfOptionalTupleMember.ts, 4, 2))
2121

2222
for (let item of foo) {
23-
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 10, 8))
24-
>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 8, 13))
23+
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8))
24+
>foo : Symbol(foo, Decl(forOfOptionalTupleMember.ts, 7, 13))
2525

2626
item.value;
2727
>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13))
28-
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 10, 8))
28+
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 8, 8))
2929
>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13))
3030
}
3131

32+
type Foo2 = [item?: Item];
33+
>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1))
34+
>Item : Symbol(Item, Decl(forOfOptionalTupleMember.ts, 0, 0))
35+
36+
declare const foo2: Foo2;
37+
>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13))
38+
>Foo2 : Symbol(Foo2, Decl(forOfOptionalTupleMember.ts, 10, 1))
39+
40+
for (let item of foo2) {
41+
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8))
42+
>foo2 : Symbol(foo2, Decl(forOfOptionalTupleMember.ts, 13, 13))
43+
44+
item.value;
45+
>item.value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13))
46+
>item : Symbol(item, Decl(forOfOptionalTupleMember.ts, 14, 8))
47+
>value : Symbol(value, Decl(forOfOptionalTupleMember.ts, 2, 13))
48+
}
49+
50+
function fn1(t: [number, number?, number?]) {
51+
>fn1 : Symbol(fn1, Decl(forOfOptionalTupleMember.ts, 16, 1))
52+
>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13))
53+
54+
for (let num of t) {
55+
>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10))
56+
>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 18, 13))
57+
58+
num.toString()
59+
>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
60+
>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 19, 10))
61+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
62+
}
63+
}
64+
65+
function fn2(t: [a: number, b?: number, c?: number]) {
66+
>fn2 : Symbol(fn2, Decl(forOfOptionalTupleMember.ts, 22, 1))
67+
>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13))
68+
69+
for (let num of t) {
70+
>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10))
71+
>t : Symbol(t, Decl(forOfOptionalTupleMember.ts, 24, 13))
72+
73+
num.toString()
74+
>num.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
75+
>num : Symbol(num, Decl(forOfOptionalTupleMember.ts, 25, 10))
76+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
77+
}
78+
}
79+

0 commit comments

Comments
 (0)