Skip to content

Commit 02d0b02

Browse files
committed
Merge pull request #378 from Microsoft/inherited_overloads_with_specialized_signatures
do not reorder signatures from derived and base types
2 parents d99fe9f + e642086 commit 02d0b02

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
@@ -3844,21 +3844,40 @@ module ts {
38443844
}
38453845

38463846
// The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
3847+
// A nit here is that we reorder only signatures that belong to the same symbol,
3848+
// so order how inherited signatures are processed is still preserved.
3849+
// interface A { (x: string): void }
3850+
// interface B extends A { (x: 'foo'): string }
3851+
// var b: B;
3852+
// b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
38473853
function collectCandidates(node: CallExpression, signatures: Signature[]): Signature[]{
38483854
var result: Signature[] = [];
38493855
var lastParent: Node;
3856+
var lastSymbol: Symbol;
3857+
var cutoffPos: number = 0;
38503858
var pos: number;
38513859
for (var i = 0; i < signatures.length; i++) {
38523860
var signature = signatures[i];
38533861
if (isCandidateSignature(node, signature)) {
3854-
var parent = signature.declaration ? signature.declaration.parent : undefined;
3855-
if (lastParent && parent === lastParent) {
3856-
pos++;
3862+
var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
3863+
var parent = signature.declaration && signature.declaration.parent;
3864+
if (!lastSymbol || symbol === lastSymbol) {
3865+
if (lastParent && parent === lastParent) {
3866+
pos++;
3867+
}
3868+
else {
3869+
lastParent = parent;
3870+
pos = cutoffPos;
3871+
}
38573872
}
38583873
else {
3874+
// current declaration belongs to a different symbol
3875+
// set cutoffPos so reorderings in the future won't change result set from 0 to cutoffPos
3876+
pos = cutoffPos = result.length;
38593877
lastParent = parent;
3860-
pos = 0;
38613878
}
3879+
lastSymbol = symbol;
3880+
38623881
for (var j = result.length; j > pos; j--) {
38633882
result[j] = result[j - 1];
38643883
}
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)