Skip to content

Commit 3c67608

Browse files
committed
When interfaces are merged, always ensure that the parent symbol of the late bound member symbol is declared symbol containing the node.
Ensure that resolvedMembers adds the late bound symbol even when its resolved sunce lateBoundMember may or may not be added to resolved members depending on when its checked Fixes microsoft#30891
1 parent 9f5090c commit 3c67608

File tree

2 files changed

+112
-3
lines changed

2 files changed

+112
-3
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6607,12 +6607,11 @@ namespace ts {
66076607
* unique symbol type which we can then use as the name of the member. This allows users
66086608
* to define custom symbols that can be used in the members of an object type.
66096609
*
6610-
* @param parent The containing symbol for the member.
66116610
* @param earlySymbols The early-bound symbols of the parent.
66126611
* @param lateSymbols The late-bound symbols of the parent.
66136612
* @param decl The member to bind.
66146613
*/
6615-
function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) {
6614+
function lateBindMember(earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) {
66166615
Debug.assert(!!decl.symbol, "The member is expected to have a symbol.");
66176616
const links = getNodeLinks(decl);
66186617
if (!links.resolvedSymbol) {
@@ -6643,6 +6642,7 @@ namespace ts {
66436642
}
66446643
lateSymbol.nameType = type;
66456644
addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags);
6645+
const parent = getSymbolOfNode(decl.parent);
66466646
if (lateSymbol.parent) {
66476647
Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one");
66486648
}
@@ -6652,6 +6652,15 @@ namespace ts {
66526652
return links.resolvedSymbol = lateSymbol;
66536653
}
66546654
}
6655+
else {
6656+
const type = checkComputedPropertyName(decl.name);
6657+
if (isTypeUsableAsPropertyName(type)) {
6658+
const memberName = getPropertyNameFromType(type);
6659+
if (!lateSymbols.has(memberName)) {
6660+
lateSymbols.set(memberName, links.resolvedSymbol);
6661+
}
6662+
}
6663+
}
66556664
return links.resolvedSymbol;
66566665
}
66576666

@@ -6675,7 +6684,7 @@ namespace ts {
66756684
if (members) {
66766685
for (const member of members) {
66776686
if (isStatic === hasStaticModifier(member) && hasLateBindableName(member)) {
6678-
lateBindMember(symbol, earlySymbols, lateSymbols, member);
6687+
lateBindMember(earlySymbols, lateSymbols, member);
66796688
}
66806689
}
66816690
}

tests/baselines/reference/tsbuild/lateBoundSymbol/incremental-declaration-doesnt-change/interface-is-merged-and-contains-late-bound-member.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
//// [/src/src/main.js]
2+
"use strict";
3+
exports.__esModule = true;
4+
var sym = Symbol();
5+
6+
17
//// [/src/src/main.ts]
28
import { HKT } from "./hkt";
39

@@ -11,3 +17,97 @@ declare module "./hkt" {
1117

1218
type A = HKT<number>[typeof sym];
1319

20+
//// [/src/tsconfig.tsbuildinfo]
21+
{
22+
"program": {
23+
"fileInfos": {
24+
"/lib/lib.es5.d.ts": {
25+
"version": "/lib/lib.es5.d.ts",
26+
"signature": "/lib/lib.es5.d.ts"
27+
},
28+
"/lib/lib.es2015.d.ts": {
29+
"version": "/lib/lib.es2015.d.ts",
30+
"signature": "/lib/lib.es2015.d.ts"
31+
},
32+
"/lib/lib.es2015.core.d.ts": {
33+
"version": "/lib/lib.es2015.core.d.ts",
34+
"signature": "/lib/lib.es2015.core.d.ts"
35+
},
36+
"/lib/lib.es2015.collection.d.ts": {
37+
"version": "/lib/lib.es2015.collection.d.ts",
38+
"signature": "/lib/lib.es2015.collection.d.ts"
39+
},
40+
"/lib/lib.es2015.generator.d.ts": {
41+
"version": "/lib/lib.es2015.generator.d.ts",
42+
"signature": "/lib/lib.es2015.generator.d.ts"
43+
},
44+
"/lib/lib.es2015.iterable.d.ts": {
45+
"version": "/lib/lib.es2015.iterable.d.ts",
46+
"signature": "/lib/lib.es2015.iterable.d.ts"
47+
},
48+
"/lib/lib.es2015.promise.d.ts": {
49+
"version": "/lib/lib.es2015.promise.d.ts",
50+
"signature": "/lib/lib.es2015.promise.d.ts"
51+
},
52+
"/lib/lib.es2015.proxy.d.ts": {
53+
"version": "/lib/lib.es2015.proxy.d.ts",
54+
"signature": "/lib/lib.es2015.proxy.d.ts"
55+
},
56+
"/lib/lib.es2015.reflect.d.ts": {
57+
"version": "/lib/lib.es2015.reflect.d.ts",
58+
"signature": "/lib/lib.es2015.reflect.d.ts"
59+
},
60+
"/lib/lib.es2015.symbol.d.ts": {
61+
"version": "/lib/lib.es2015.symbol.d.ts",
62+
"signature": "/lib/lib.es2015.symbol.d.ts"
63+
},
64+
"/lib/lib.es2015.symbol.wellknown.d.ts": {
65+
"version": "/lib/lib.es2015.symbol.wellknown.d.ts",
66+
"signature": "/lib/lib.es2015.symbol.wellknown.d.ts"
67+
},
68+
"/src/src/hkt.ts": {
69+
"version": "675797797",
70+
"signature": "2373810515"
71+
},
72+
"/src/src/main.ts": {
73+
"version": "-27494779858",
74+
"signature": "-7779857705"
75+
}
76+
},
77+
"options": {
78+
"rootDir": "/src/src",
79+
"lib": [
80+
"lib.es2015.d.ts"
81+
],
82+
"incremental": true,
83+
"configFilePath": "/src/tsconfig.json"
84+
},
85+
"referencedMap": {
86+
"/src/src/main.ts": [
87+
"/src/src/hkt.ts"
88+
]
89+
},
90+
"exportedModulesMap": {
91+
"/src/src/main.ts": [
92+
"/src/src/hkt.ts"
93+
]
94+
},
95+
"semanticDiagnosticsPerFile": [
96+
"/lib/lib.es2015.collection.d.ts",
97+
"/lib/lib.es2015.core.d.ts",
98+
"/lib/lib.es2015.d.ts",
99+
"/lib/lib.es2015.generator.d.ts",
100+
"/lib/lib.es2015.iterable.d.ts",
101+
"/lib/lib.es2015.promise.d.ts",
102+
"/lib/lib.es2015.proxy.d.ts",
103+
"/lib/lib.es2015.reflect.d.ts",
104+
"/lib/lib.es2015.symbol.d.ts",
105+
"/lib/lib.es2015.symbol.wellknown.d.ts",
106+
"/lib/lib.es5.d.ts",
107+
"/src/src/hkt.ts",
108+
"/src/src/main.ts"
109+
]
110+
},
111+
"version": "FakeTSVersion"
112+
}
113+

0 commit comments

Comments
 (0)