Skip to content

Commit 027d6b4

Browse files
committed
Notes about the bug: There were in fact two bugs, as was initially suggested by @Mhehazy. The first lead to properties not being found inside optional object binding patterns. The second lead to a function not being assignable to another when it actually should have. Both bugs were fixed. Addes more testcases.
1 parent 2a008c2 commit 027d6b4

5 files changed

+401
-14
lines changed

src/compiler/checker.ts

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17658,20 +17658,42 @@ namespace ts {
1765817658
}
1765917659

1766017660
function getOptionalTypeRecursive(type: Type) {
17661-
if(!(type.flags & TypeFlags.Object)) {
17662-
return type;
17663-
}
17664-
let type2 = type as ResolvedType;
17665-
17666-
let x = type2.properties.length
17667-
for(let i=0;i<x;i++) {
17668-
let prop = type2.properties[i] as SymbolLinks;
17669-
if(prop.bindingElement && prop.bindingElement.initializer) {
17670-
prop.type = getOptionalType(prop.type)
17671-
type2.properties[i] = prop as Symbol;
17672-
}
17673-
}
17674-
return type as Type;
17661+
if ((type as ResolvedType).properties) {
17662+
const rType = type as ResolvedType;
17663+
const propCount = rType.properties.length;
17664+
17665+
if (rType.flags & TypeFlags.Object) {
17666+
for (let i = 0; i < propCount; i++) {
17667+
const prop = rType.properties[i] as SymbolLinks;
17668+
let innerType;
17669+
if (prop.bindingElement && prop.bindingElement.initializer) {
17670+
innerType = getOptionalTypeRecursive(prop.type);
17671+
innerType = getOptionalType(innerType);
17672+
}
17673+
else if (prop.type.symbol) {
17674+
innerType = getTypeOfParameter(prop.type.symbol);
17675+
}
17676+
else {
17677+
innerType = prop.type;
17678+
}
17679+
prop.type = innerType;
17680+
rType.properties[i] = prop as Symbol;
17681+
}
17682+
}
17683+
17684+
if (type.flags & TypeFlags.Union || type.flags & TypeFlags.Intersection) {
17685+
for (let i = 0; i < propCount; i++) {
17686+
const prop = rType.properties[i] as SymbolLinks;
17687+
const innerType = getOptionalTypeRecursive(prop.type);
17688+
prop.type = innerType;
17689+
rType.properties[i] = prop as Symbol;
17690+
}
17691+
}
17692+
return rType as Type;
17693+
}
17694+
else {
17695+
return type;
17696+
}
1767517697
}
1767617698

1767717699
function getTypeOfParameter(symbol: Symbol) {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//// [compareTypeSignaturesWithOptionalParameters.ts]
2+
let x1: (a?: {b?:number, c?:number}) => void;
3+
x1 = ({b = 1, c = 2} = {}) => {};
4+
const x2 = ({b = 1, c = 2} = {}) => {};
5+
x1 = x2;
6+
7+
let x3: (a?: {b?:number, c?:{d?:number, e?:number}}) => void;
8+
x3 = ({b = 1, c:{d = 2, e = 3} = {}} = {}) => {};
9+
const x4 = ({b = 1, c:{d = 2, e = 3} = {}} = {}) => {};
10+
x3 = x4;
11+
12+
let x5: (a?: {b?:number, c?:{d?:{f?:number, g?:number}, e?:number}}) => void;
13+
x5 = ({b = 1, c:{d:{f = 4, g = 5} = {}, e = 3} = {}} = {}) => {};
14+
const x6 = ({b = 1, c:{d:{f = 4, g = 5} = {}, e = 3} = {}} = {}) => {};
15+
x5 = x6;
16+
17+
let useImplementation1 = true;
18+
let someOtherFunctionOfThisType = ({a = 3, b = 4} = {}) => a + b;
19+
let adder: (nums?: {a?:number, b?:number}) => number;
20+
if (useImplementation1) {
21+
adder = ({a = 1, b = 2} = {}) => a + b;
22+
} else {
23+
adder = someOtherFunctionOfThisType;
24+
}
25+
26+
27+
//// [compareTypeSignaturesWithOptionalParameters.js]
28+
"use strict";
29+
var x1;
30+
x1 = function (_a) {
31+
var _b = _a === void 0 ? {} : _a, _c = _b.b, b = _c === void 0 ? 1 : _c, _d = _b.c, c = _d === void 0 ? 2 : _d;
32+
};
33+
var x2 = function (_a) {
34+
var _b = _a === void 0 ? {} : _a, _c = _b.b, b = _c === void 0 ? 1 : _c, _d = _b.c, c = _d === void 0 ? 2 : _d;
35+
};
36+
x1 = x2;
37+
var x3;
38+
x3 = function (_a) {
39+
var _b = _a === void 0 ? {} : _a, _c = _b.b, b = _c === void 0 ? 1 : _c, _d = _b.c, _e = _d === void 0 ? {} : _d, _f = _e.d, d = _f === void 0 ? 2 : _f, _g = _e.e, e = _g === void 0 ? 3 : _g;
40+
};
41+
var x4 = function (_a) {
42+
var _b = _a === void 0 ? {} : _a, _c = _b.b, b = _c === void 0 ? 1 : _c, _d = _b.c, _e = _d === void 0 ? {} : _d, _f = _e.d, d = _f === void 0 ? 2 : _f, _g = _e.e, e = _g === void 0 ? 3 : _g;
43+
};
44+
x3 = x4;
45+
var x5;
46+
x5 = function (_a) {
47+
var _b = _a === void 0 ? {} : _a, _c = _b.b, b = _c === void 0 ? 1 : _c, _d = _b.c, _e = _d === void 0 ? {} : _d, _f = _e.d, _g = _f === void 0 ? {} : _f, _h = _g.f, f = _h === void 0 ? 4 : _h, _j = _g.g, g = _j === void 0 ? 5 : _j, _k = _e.e, e = _k === void 0 ? 3 : _k;
48+
};
49+
var x6 = function (_a) {
50+
var _b = _a === void 0 ? {} : _a, _c = _b.b, b = _c === void 0 ? 1 : _c, _d = _b.c, _e = _d === void 0 ? {} : _d, _f = _e.d, _g = _f === void 0 ? {} : _f, _h = _g.f, f = _h === void 0 ? 4 : _h, _j = _g.g, g = _j === void 0 ? 5 : _j, _k = _e.e, e = _k === void 0 ? 3 : _k;
51+
};
52+
x5 = x6;
53+
var useImplementation1 = true;
54+
var someOtherFunctionOfThisType = function (_a) {
55+
var _b = _a === void 0 ? {} : _a, _c = _b.a, a = _c === void 0 ? 3 : _c, _d = _b.b, b = _d === void 0 ? 4 : _d;
56+
return a + b;
57+
};
58+
var adder;
59+
if (useImplementation1) {
60+
adder = function (_a) {
61+
var _b = _a === void 0 ? {} : _a, _c = _b.a, a = _c === void 0 ? 1 : _c, _d = _b.b, b = _d === void 0 ? 2 : _d;
62+
return a + b;
63+
};
64+
}
65+
else {
66+
adder = someOtherFunctionOfThisType;
67+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
=== tests/cases/compiler/compareTypeSignaturesWithOptionalParameters.ts ===
2+
let x1: (a?: {b?:number, c?:number}) => void;
3+
>x1 : Symbol(x1, Decl(compareTypeSignaturesWithOptionalParameters.ts, 0, 3))
4+
>a : Symbol(a, Decl(compareTypeSignaturesWithOptionalParameters.ts, 0, 9))
5+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 0, 14))
6+
>c : Symbol(c, Decl(compareTypeSignaturesWithOptionalParameters.ts, 0, 24))
7+
8+
x1 = ({b = 1, c = 2} = {}) => {};
9+
>x1 : Symbol(x1, Decl(compareTypeSignaturesWithOptionalParameters.ts, 0, 3))
10+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 1, 7))
11+
>c : Symbol(c, Decl(compareTypeSignaturesWithOptionalParameters.ts, 1, 13))
12+
13+
const x2 = ({b = 1, c = 2} = {}) => {};
14+
>x2 : Symbol(x2, Decl(compareTypeSignaturesWithOptionalParameters.ts, 2, 5))
15+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 2, 13))
16+
>c : Symbol(c, Decl(compareTypeSignaturesWithOptionalParameters.ts, 2, 19))
17+
18+
x1 = x2;
19+
>x1 : Symbol(x1, Decl(compareTypeSignaturesWithOptionalParameters.ts, 0, 3))
20+
>x2 : Symbol(x2, Decl(compareTypeSignaturesWithOptionalParameters.ts, 2, 5))
21+
22+
let x3: (a?: {b?:number, c?:{d?:number, e?:number}}) => void;
23+
>x3 : Symbol(x3, Decl(compareTypeSignaturesWithOptionalParameters.ts, 5, 3))
24+
>a : Symbol(a, Decl(compareTypeSignaturesWithOptionalParameters.ts, 5, 9))
25+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 5, 14))
26+
>c : Symbol(c, Decl(compareTypeSignaturesWithOptionalParameters.ts, 5, 24))
27+
>d : Symbol(d, Decl(compareTypeSignaturesWithOptionalParameters.ts, 5, 29))
28+
>e : Symbol(e, Decl(compareTypeSignaturesWithOptionalParameters.ts, 5, 39))
29+
30+
x3 = ({b = 1, c:{d = 2, e = 3} = {}} = {}) => {};
31+
>x3 : Symbol(x3, Decl(compareTypeSignaturesWithOptionalParameters.ts, 5, 3))
32+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 6, 7))
33+
>d : Symbol(d, Decl(compareTypeSignaturesWithOptionalParameters.ts, 6, 17))
34+
>e : Symbol(e, Decl(compareTypeSignaturesWithOptionalParameters.ts, 6, 23))
35+
36+
const x4 = ({b = 1, c:{d = 2, e = 3} = {}} = {}) => {};
37+
>x4 : Symbol(x4, Decl(compareTypeSignaturesWithOptionalParameters.ts, 7, 5))
38+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 7, 13))
39+
>c : Symbol(c)
40+
>d : Symbol(d, Decl(compareTypeSignaturesWithOptionalParameters.ts, 7, 23))
41+
>e : Symbol(e, Decl(compareTypeSignaturesWithOptionalParameters.ts, 7, 29))
42+
43+
x3 = x4;
44+
>x3 : Symbol(x3, Decl(compareTypeSignaturesWithOptionalParameters.ts, 5, 3))
45+
>x4 : Symbol(x4, Decl(compareTypeSignaturesWithOptionalParameters.ts, 7, 5))
46+
47+
let x5: (a?: {b?:number, c?:{d?:{f?:number, g?:number}, e?:number}}) => void;
48+
>x5 : Symbol(x5, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 3))
49+
>a : Symbol(a, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 9))
50+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 14))
51+
>c : Symbol(c, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 24))
52+
>d : Symbol(d, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 29))
53+
>f : Symbol(f, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 33))
54+
>g : Symbol(g, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 43))
55+
>e : Symbol(e, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 55))
56+
57+
x5 = ({b = 1, c:{d:{f = 4, g = 5} = {}, e = 3} = {}} = {}) => {};
58+
>x5 : Symbol(x5, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 3))
59+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 11, 7))
60+
>d : Symbol(d, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 29))
61+
>f : Symbol(f, Decl(compareTypeSignaturesWithOptionalParameters.ts, 11, 20))
62+
>g : Symbol(g, Decl(compareTypeSignaturesWithOptionalParameters.ts, 11, 26))
63+
>e : Symbol(e, Decl(compareTypeSignaturesWithOptionalParameters.ts, 11, 39))
64+
65+
const x6 = ({b = 1, c:{d:{f = 4, g = 5} = {}, e = 3} = {}} = {}) => {};
66+
>x6 : Symbol(x6, Decl(compareTypeSignaturesWithOptionalParameters.ts, 12, 5))
67+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 12, 13))
68+
>c : Symbol(c)
69+
>f : Symbol(f, Decl(compareTypeSignaturesWithOptionalParameters.ts, 12, 26))
70+
>g : Symbol(g, Decl(compareTypeSignaturesWithOptionalParameters.ts, 12, 32))
71+
>e : Symbol(e, Decl(compareTypeSignaturesWithOptionalParameters.ts, 12, 45))
72+
73+
x5 = x6;
74+
>x5 : Symbol(x5, Decl(compareTypeSignaturesWithOptionalParameters.ts, 10, 3))
75+
>x6 : Symbol(x6, Decl(compareTypeSignaturesWithOptionalParameters.ts, 12, 5))
76+
77+
let useImplementation1 = true;
78+
>useImplementation1 : Symbol(useImplementation1, Decl(compareTypeSignaturesWithOptionalParameters.ts, 15, 3))
79+
80+
let someOtherFunctionOfThisType = ({a = 3, b = 4} = {}) => a + b;
81+
>someOtherFunctionOfThisType : Symbol(someOtherFunctionOfThisType, Decl(compareTypeSignaturesWithOptionalParameters.ts, 16, 3))
82+
>a : Symbol(a, Decl(compareTypeSignaturesWithOptionalParameters.ts, 16, 36))
83+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 16, 42))
84+
>a : Symbol(a, Decl(compareTypeSignaturesWithOptionalParameters.ts, 16, 36))
85+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 16, 42))
86+
87+
let adder: (nums?: {a?:number, b?:number}) => number;
88+
>adder : Symbol(adder, Decl(compareTypeSignaturesWithOptionalParameters.ts, 17, 3))
89+
>nums : Symbol(nums, Decl(compareTypeSignaturesWithOptionalParameters.ts, 17, 12))
90+
>a : Symbol(a, Decl(compareTypeSignaturesWithOptionalParameters.ts, 17, 20))
91+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 17, 30))
92+
93+
if (useImplementation1) {
94+
>useImplementation1 : Symbol(useImplementation1, Decl(compareTypeSignaturesWithOptionalParameters.ts, 15, 3))
95+
96+
adder = ({a = 1, b = 2} = {}) => a + b;
97+
>adder : Symbol(adder, Decl(compareTypeSignaturesWithOptionalParameters.ts, 17, 3))
98+
>a : Symbol(a, Decl(compareTypeSignaturesWithOptionalParameters.ts, 19, 12))
99+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 19, 18))
100+
>a : Symbol(a, Decl(compareTypeSignaturesWithOptionalParameters.ts, 19, 12))
101+
>b : Symbol(b, Decl(compareTypeSignaturesWithOptionalParameters.ts, 19, 18))
102+
103+
} else {
104+
adder = someOtherFunctionOfThisType;
105+
>adder : Symbol(adder, Decl(compareTypeSignaturesWithOptionalParameters.ts, 17, 3))
106+
>someOtherFunctionOfThisType : Symbol(someOtherFunctionOfThisType, Decl(compareTypeSignaturesWithOptionalParameters.ts, 16, 3))
107+
}
108+

0 commit comments

Comments
 (0)