Skip to content

Commit 236e24b

Browse files
committed
do not reorder signatures from derived and base types
1 parent 97987b1 commit 236e24b

File tree

3 files changed

+106
-4
lines changed

3 files changed

+106
-4
lines changed

src/compiler/checker.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3793,21 +3793,40 @@ module ts {
37933793
}
37943794

37953795
// The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
3796+
// A nit here is that we reorder only signatures that belong to the same symbol,
3797+
// so order how inherited signatures are processed is still preserved.
3798+
// interface A { (x: string): void }
3799+
// interface B { (x: 'foo'): string }
3800+
// var b: B;
3801+
// b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
37963802
function collectCandidates(node: CallExpression, signatures: Signature[]): Signature[]{
37973803
var result: Signature[] = [];
37983804
var lastParent: Node;
3805+
var lastSymbol: Symbol;
3806+
var cutoffPos: number = 0;
37993807
var pos: number;
38003808
for (var i = 0; i < signatures.length; i++) {
38013809
var signature = signatures[i];
38023810
if (isCandidateSignature(node, signature)) {
3803-
var parent = signature.declaration ? signature.declaration.parent : undefined;
3804-
if (lastParent && parent === lastParent) {
3805-
pos++;
3811+
var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
3812+
var parent = signature.declaration && signature.declaration.parent;
3813+
if (!lastSymbol || symbol === lastSymbol) {
3814+
if (lastParent && parent === lastParent) {
3815+
pos++;
3816+
}
3817+
else {
3818+
lastParent = parent;
3819+
pos = cutoffPos;
3820+
}
38063821
}
38073822
else {
3823+
// current declaration belongs to a different symbol
3824+
// set cutoffPos so reorderings in the future won't change result set from 0 to cutoffPos
3825+
pos = cutoffPos = result.length;
38083826
lastParent = parent;
3809-
pos = 0;
38103827
}
3828+
lastSymbol = symbol;
3829+
38113830
for (var j = result.length; j > pos; j--) {
38123831
result[j] = result[j - 1];
38133832
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//// [inheritedOverloadedSpecializedSignatures.ts]
2+
interface A {
3+
(key:string):void;
4+
}
5+
6+
interface B extends A {
7+
(key:'foo'):string;
8+
}
9+
10+
var b:B;
11+
// Should not error
12+
b('foo').charAt(0);
13+
14+
interface A {
15+
(x: 'A1'): string;
16+
(x: string): void;
17+
}
18+
19+
interface B extends A {
20+
(x: 'B1'): number;
21+
}
22+
23+
interface A {
24+
(x: 'A2'): boolean;
25+
}
26+
27+
interface B {
28+
(x: 'B2'): string[];
29+
}
30+
31+
var b: B;
32+
// non of these lines should error
33+
var x1: string[] = b('B2');
34+
var x2: number = b('B1');
35+
var x3: boolean = b('A2');
36+
var x4: string = b('A1');
37+
var x5: void = b('A0');
38+
39+
//// [inheritedOverloadedSpecializedSignatures.js]
40+
var b;
41+
b('foo').charAt(0);
42+
var b;
43+
var x1 = b('B2');
44+
var x2 = b('B1');
45+
var x3 = b('A2');
46+
var x4 = b('A1');
47+
var x5 = b('A0');
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
interface A {
2+
(key:string):void;
3+
}
4+
5+
interface B extends A {
6+
(key:'foo'):string;
7+
}
8+
9+
var b:B;
10+
// Should not error
11+
b('foo').charAt(0);
12+
13+
interface A {
14+
(x: 'A1'): string;
15+
(x: string): void;
16+
}
17+
18+
interface B extends A {
19+
(x: 'B1'): number;
20+
}
21+
22+
interface A {
23+
(x: 'A2'): boolean;
24+
}
25+
26+
interface B {
27+
(x: 'B2'): string[];
28+
}
29+
30+
var b: B;
31+
// non of these lines should error
32+
var x1: string[] = b('B2');
33+
var x2: number = b('B1');
34+
var x3: boolean = b('A2');
35+
var x4: string = b('A1');
36+
var x5: void = b('A0');

0 commit comments

Comments
 (0)