Skip to content

Commit 60b6506

Browse files
committed
fix: Properly resolve type parameters
Closes #1438
1 parent 1153735 commit 60b6506

File tree

10 files changed

+65
-40
lines changed

10 files changed

+65
-40
lines changed

src/lib/converter/context.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ export class Context {
5959
*/
6060
readonly scope: Reflection;
6161

62+
/** @internal */
63+
isConvertingTypeNode(): boolean {
64+
return this.convertingTypeNode;
65+
}
66+
67+
/** @internal */
68+
setConvertingTypeNode() {
69+
this.convertingTypeNode = true;
70+
}
71+
72+
private convertingTypeNode = false;
73+
6274
/**
6375
* Create a new Context instance.
6476
*
@@ -231,6 +243,7 @@ export class Context {
231243
this.project,
232244
scope
233245
);
246+
context.convertingTypeNode = this.convertingTypeNode;
234247
context.setActiveProgram(this._program);
235248
return context;
236249
}

src/lib/converter/symbols.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ function convertTypeAlias(
200200
);
201201

202202
reflection.type = context.converter.convertType(
203-
context,
203+
context.withScope(reflection),
204204
declaration.type
205205
);
206206

@@ -550,7 +550,7 @@ function convertProperty(
550550
// parent node. This will probably break in a future TS version.
551551
reflection.type = context.converter.convertType(
552552
context,
553-
parameterType ??
553+
(context.isConvertingTypeNode() ? parameterType : void 0) ??
554554
context.checker.getTypeOfSymbolAtLocation(symbol, {} as any)
555555
);
556556
}

src/lib/converter/types.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export function convertType(
124124
if (symbol) {
125125
if (
126126
node.kind !== ts.SyntaxKind.TypeReference &&
127+
node.kind !== ts.SyntaxKind.ArrayType &&
127128
seenTypeSymbols.has(symbol)
128129
) {
129130
const typeString = context.checker.typeToString(typeOrNode);
@@ -196,6 +197,9 @@ const constructorConverter: TypeConverter<ts.ConstructorTypeNode, ts.Type> = {
196197
ReflectionKind.Constructor,
197198
context.scope
198199
);
200+
const rc = context.withScope(reflection);
201+
rc.setConvertingTypeNode();
202+
199203
context.registerReflection(reflection, symbol);
200204
context.trigger(ConverterEvents.CREATE_DECLARATION, reflection, node);
201205

@@ -205,7 +209,7 @@ const constructorConverter: TypeConverter<ts.ConstructorTypeNode, ts.Type> = {
205209
reflection
206210
);
207211
context.registerReflection(signature, void 0);
208-
const signatureCtx = context.withScope(signature);
212+
const signatureCtx = rc.withScope(signature);
209213

210214
reflection.signatures = [signature];
211215
signature.type = convertType(signatureCtx, node.type);
@@ -215,7 +219,7 @@ const constructorConverter: TypeConverter<ts.ConstructorTypeNode, ts.Type> = {
215219
node.parameters
216220
);
217221
signature.typeParameters = convertTypeParameterNodes(
218-
context.withScope(reflection),
222+
signatureCtx,
219223
node.typeParameters
220224
);
221225

@@ -287,6 +291,8 @@ const functionTypeConverter: TypeConverter<ts.FunctionTypeNode, ts.Type> = {
287291
ReflectionKind.TypeLiteral,
288292
context.scope
289293
);
294+
const rc = context.withScope(reflection);
295+
290296
context.registerReflection(reflection, symbol);
291297
context.trigger(ConverterEvents.CREATE_DECLARATION, reflection, node);
292298

@@ -296,7 +302,7 @@ const functionTypeConverter: TypeConverter<ts.FunctionTypeNode, ts.Type> = {
296302
reflection
297303
);
298304
context.registerReflection(signature, void 0);
299-
const signatureCtx = context.withScope(signature);
305+
const signatureCtx = rc.withScope(signature);
300306

301307
reflection.signatures = [signature];
302308
signature.type = convertType(signatureCtx, node.type);
@@ -306,7 +312,7 @@ const functionTypeConverter: TypeConverter<ts.FunctionTypeNode, ts.Type> = {
306312
node.parameters
307313
);
308314
signature.typeParameters = convertTypeParameterNodes(
309-
context.withScope(reflection),
315+
signatureCtx,
310316
node.typeParameters
311317
);
312318

@@ -468,24 +474,23 @@ const typeLiteralConverter: TypeConverter<ts.TypeLiteralNode> = {
468474
ReflectionKind.TypeLiteral,
469475
context.scope
470476
);
477+
const rc = context.withScope(reflection);
478+
rc.setConvertingTypeNode();
479+
471480
context.registerReflection(reflection, symbol);
472481
context.trigger(ConverterEvents.CREATE_DECLARATION, reflection, node);
473482

474483
for (const prop of context.checker.getPropertiesOfType(type)) {
475-
convertSymbol(context.withScope(reflection), prop);
484+
convertSymbol(rc, prop);
476485
}
477486
for (const signature of type.getCallSignatures()) {
478487
reflection.signatures ??= [];
479488
reflection.signatures.push(
480-
createSignature(
481-
context.withScope(reflection),
482-
ReflectionKind.CallSignature,
483-
signature
484-
)
489+
createSignature(rc, ReflectionKind.CallSignature, signature)
485490
);
486491
}
487492

488-
convertIndexSignature(context.withScope(reflection), symbol);
493+
convertIndexSignature(rc, symbol);
489494

490495
return new ReflectionType(reflection);
491496
},
@@ -575,10 +580,12 @@ const referenceConverter: TypeConverter<
575580
convertType(context, type) {
576581
const symbol = type.aliasSymbol ?? type.getSymbol();
577582
if (!symbol) {
578-
// If we get in here, the user is doing something bad. Probably using mixins.
579-
const broken = new UnknownType(context.checker.typeToString(type));
580-
context.logger.warn(`Bad reference type: ${broken.name}`);
581-
return broken;
583+
// This happens when we get a reference to a type parameter
584+
// created within a mapped type, `K` in: `{ [K in T]: string }`
585+
return ReferenceType.createBrokenReference(
586+
context.checker.typeToString(type),
587+
context.project
588+
);
582589
}
583590

584591
const ref = new ReferenceType(

src/lib/models/types/reference.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ export class ReferenceType extends Type {
3333
* The resolved reflection.
3434
*/
3535
get reflection() {
36-
if (this._target instanceof Reflection) {
37-
return this._target;
36+
if (typeof this._target === "number") {
37+
return this._project.getReflectionById(this._target);
3838
}
3939
const resolved = this._project.getReflectionFromSymbol(this._target);
40-
if (resolved) this._target = resolved;
40+
if (resolved) this._target = resolved.id;
4141
return resolved;
4242
}
4343

@@ -47,23 +47,28 @@ export class ReferenceType extends Type {
4747
*/
4848
getReflection = () => this.reflection;
4949

50-
private _target: ts.Symbol | Reflection;
50+
private _target: ts.Symbol | number;
5151
private _project: ProjectReflection;
5252

5353
/**
5454
* Create a new instance of ReferenceType.
5555
*/
5656
constructor(
5757
name: string,
58-
target: ts.Symbol | Reflection,
58+
target: ts.Symbol | Reflection | number,
5959
project: ProjectReflection
6060
) {
6161
super();
6262
this.name = name;
63-
this._target = target;
63+
this._target = target instanceof Reflection ? target.id : target;
6464
this._project = project;
6565
}
6666

67+
/** @internal this is used for type parameters, which don't actually point to something */
68+
static createBrokenReference(name: string, project: ProjectReflection) {
69+
return new ReferenceType(name, -1, project);
70+
}
71+
6772
/**
6873
* Clone this type.
6974
*

src/test/converter/class/specs-with-lump-categories.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2905,8 +2905,8 @@
29052905
"shortText": "Generic property."
29062906
},
29072907
"type": {
2908-
"type": "reference",
2909-
"name": "T"
2908+
"type": "intrinsic",
2909+
"name": "string"
29102910
},
29112911
"inheritedFrom": {
29122912
"type": "reference",
@@ -2928,8 +2928,8 @@
29282928
"type": {
29292929
"type": "array",
29302930
"elementType": {
2931-
"type": "reference",
2932-
"name": "T"
2931+
"type": "intrinsic",
2932+
"name": "string"
29332933
}
29342934
},
29352935
"inheritedFrom": {

src/test/converter/class/specs.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,8 +2901,8 @@
29012901
"shortText": "Generic property."
29022902
},
29032903
"type": {
2904-
"type": "reference",
2905-
"name": "T"
2904+
"type": "intrinsic",
2905+
"name": "string"
29062906
},
29072907
"inheritedFrom": {
29082908
"type": "reference",
@@ -2924,8 +2924,8 @@
29242924
"type": {
29252925
"type": "array",
29262926
"elementType": {
2927-
"type": "reference",
2928-
"name": "T"
2927+
"type": "intrinsic",
2928+
"name": "string"
29292929
}
29302930
},
29312931
"inheritedFrom": {

src/test/converter/types/specs.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,10 @@
880880
"elementType": {
881881
"type": "union",
882882
"types": [
883+
{
884+
"type": "intrinsic",
885+
"name": "string"
886+
},
883887
{
884888
"type": "array",
885889
"elementType": {
@@ -897,10 +901,6 @@
897901
}
898902
]
899903
}
900-
},
901-
{
902-
"type": "intrinsic",
903-
"name": "string"
904904
}
905905
]
906906
}

src/test/renderer/specs/classes/classes.baseclass.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ <h2>Properties</h2>
179179
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class tsd-is-private">
180180
<a name="internalclass" class="tsd-anchor"></a>
181181
<h3><span class="tsd-flag ts-flagPrivate">Private</span> internal<wbr>Class</h3>
182-
<div class="tsd-signature tsd-kind-icon">internal<wbr>Class<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">InternalClass</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-symbol">keyof </span><a href="classes.baseclass.html" class="tsd-signature-type" data-tsd-kind="Class">BaseClass</a><span class="tsd-signature-symbol">&gt;</span></div>
182+
<div class="tsd-signature tsd-kind-icon">internal<wbr>Class<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">InternalClass</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">&quot;name&quot;</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">&quot;abstractMethod&quot;</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">&quot;getName&quot;</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">&quot;setName&quot;</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">&quot;arrowFunction&quot;</span><span class="tsd-signature-symbol">&gt;</span></div>
183183
<aside class="tsd-sources">
184184
</aside>
185185
<div class="tsd-comment tsd-typography">

src/test/renderer/specs/classes/classes.nongenericclass.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ <h2>Properties</h2>
178178
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class tsd-is-inherited tsd-is-protected">
179179
<a name="p2" class="tsd-anchor"></a>
180180
<h3><span class="tsd-flag ts-flagProtected">Protected</span> p2</h3>
181-
<div class="tsd-signature tsd-kind-icon">p2<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">T</span></div>
181+
<div class="tsd-signature tsd-kind-icon">p2<span class="tsd-signature-symbol">:</span> <a href="classes.subclassb.html" class="tsd-signature-type" data-tsd-kind="Class">SubClassB</a></div>
182182
<aside class="tsd-sources">
183183
<p>Inherited from <a href="classes.genericclass.html">GenericClass</a>.<a href="classes.genericclass.html#p2">p2</a></p>
184184
</aside>
@@ -202,7 +202,7 @@ <h3><span class="tsd-flag ts-flagReadonly">Readonly</span> p5</h3>
202202
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class tsd-is-inherited">
203203
<a name="value" class="tsd-anchor"></a>
204204
<h3>value</h3>
205-
<div class="tsd-signature tsd-kind-icon">value<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">T</span></div>
205+
<div class="tsd-signature tsd-kind-icon">value<span class="tsd-signature-symbol">:</span> <a href="classes.subclassb.html" class="tsd-signature-type" data-tsd-kind="Class">SubClassB</a></div>
206206
<aside class="tsd-sources">
207207
<p>Inherited from <a href="classes.genericclass.html">GenericClass</a>.<a href="classes.genericclass.html#value">value</a></p>
208208
</aside>

src/test/renderer/specs/modules/mixin.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ <h4>A = <span class="tsd-signature-type">object</span></h4>
126126
<h4>Type declaration</h4>
127127
<ul class="tsd-parameters">
128128
<li class="tsd-parameter-signature">
129-
<ul class="tsd-signatures tsd-kind-constructor tsd-parent-kind-module">
129+
<ul class="tsd-signatures tsd-kind-constructor tsd-parent-kind-type-alias">
130130
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">...</span>input<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">A</span></li>
131131
</ul>
132132
<ul class="tsd-descriptions">
@@ -165,7 +165,7 @@ <h4>A = <span class="tsd-signature-type">any</span></h4>
165165
<h4>Type declaration</h4>
166166
<ul class="tsd-parameters">
167167
<li class="tsd-parameter-signature">
168-
<ul class="tsd-signatures tsd-kind-type-literal tsd-parent-kind-module">
168+
<ul class="tsd-signatures tsd-kind-type-literal tsd-parent-kind-type-alias">
169169
<li class="tsd-signature tsd-kind-icon"><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">...</span>input<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">A</span></li>
170170
</ul>
171171
<ul class="tsd-descriptions">

0 commit comments

Comments
 (0)