Skip to content

Commit

Permalink
fix: Crash when converting recursive type alias
Browse files Browse the repository at this point in the history
Resolves #1547
  • Loading branch information
Gerrit0 committed Mar 25, 2021
1 parent ce218e9 commit 02fe2a7
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 6 deletions.
15 changes: 10 additions & 5 deletions src/lib/converter/types.ts
Expand Up @@ -121,11 +121,6 @@ export function convertType(
return requestBugReport(context, typeOrNode);
}

// TS 4.2 added this to enable better tracking of type aliases.
if (typeOrNode.isUnion() && typeOrNode.origin) {
return convertType(context, typeOrNode.origin);
}

// IgnoreErrors is important, without it, we can't assert that we will get a node.
const node = context.checker.typeToTypeNode(
typeOrNode,
Expand Down Expand Up @@ -952,6 +947,11 @@ const typeOperatorConverter: TypeConverter<ts.TypeOperatorNode> = {
// keyof will only show up with generic functions, otherwise it gets eagerly
// resolved to a union of strings.
if (node.operator === ts.SyntaxKind.KeyOfKeyword) {
// TS 4.2 added this to enable better tracking of type aliases.
if (type.isUnion() && type.origin) {
return convertType(context, type.origin);
}

// There's probably an interface for this somewhere... I couldn't find it.
const targetType = (type as ts.Type & { type: ts.Type }).type;
return new TypeOperatorType(
Expand All @@ -974,6 +974,11 @@ const unionConverter: TypeConverter<ts.UnionTypeNode, ts.UnionType> = {
);
},
convertType(context, type) {
// TS 4.2 added this to enable better tracking of type aliases.
if (type.origin) {
return convertType(context, type.origin);
}

return new UnionType(
type.types.map((type) => convertType(context, type))
);
Expand Down
28 changes: 28 additions & 0 deletions src/test/converter/alias/alias.ts
Expand Up @@ -73,3 +73,31 @@ export namespace GH1454 {
export declare function bar(x: Bar): Bar;
export declare function foo(x: Foo): Foo;
}

export namespace GH1547 {
export interface ThingA {
type: "ThingA";
}

export interface ThingB {
type: "ThingB";
}

type Things = ThingA | ThingB;

type ValueOrArray<T> = T | Array<ValueOrArray<T>>;

/**
* Test.
*/
export class Test {
/**
* Log a thing.
*
* @param things - Array of things or a thing.
*/
log_thing(things: ValueOrArray<Things>): void {
console.log(things);
}
}
}
181 changes: 180 additions & 1 deletion src/test/converter/alias/specs.json
Expand Up @@ -375,6 +375,184 @@
}
]
},
{
"id": 52,
"name": "GH1547",
"kind": 2,
"kindString": "Namespace",
"flags": {},
"children": [
{
"id": 57,
"name": "Test",
"kind": 128,
"kindString": "Class",
"flags": {},
"comment": {
"shortText": "Test."
},
"children": [
{
"id": 58,
"name": "constructor",
"kind": 512,
"kindString": "Constructor",
"flags": {},
"signatures": [
{
"id": 59,
"name": "new Test",
"kind": 16384,
"kindString": "Constructor signature",
"flags": {},
"type": {
"type": "reference",
"id": 57,
"name": "Test"
}
}
]
},
{
"id": 60,
"name": "log_thing",
"kind": 2048,
"kindString": "Method",
"flags": {},
"signatures": [
{
"id": 61,
"name": "log_thing",
"kind": 4096,
"kindString": "Call signature",
"flags": {},
"comment": {
"shortText": "Log a thing."
},
"parameters": [
{
"id": 62,
"name": "things",
"kind": 32768,
"kindString": "Parameter",
"flags": {},
"comment": {
"text": "Array of things or a thing.\n"
},
"type": {
"type": "reference",
"typeArguments": [
{
"type": "reference",
"name": "Things"
}
],
"name": "ValueOrArray"
}
}
],
"type": {
"type": "intrinsic",
"name": "void"
}
}
]
}
],
"groups": [
{
"title": "Constructors",
"kind": 512,
"children": [
58
]
},
{
"title": "Methods",
"kind": 2048,
"children": [
60
]
}
]
},
{
"id": 53,
"name": "ThingA",
"kind": 256,
"kindString": "Interface",
"flags": {},
"children": [
{
"id": 54,
"name": "type",
"kind": 1024,
"kindString": "Property",
"flags": {},
"type": {
"type": "literal",
"value": "ThingA"
}
}
],
"groups": [
{
"title": "Properties",
"kind": 1024,
"children": [
54
]
}
]
},
{
"id": 55,
"name": "ThingB",
"kind": 256,
"kindString": "Interface",
"flags": {},
"children": [
{
"id": 56,
"name": "type",
"kind": 1024,
"kindString": "Property",
"flags": {},
"type": {
"type": "literal",
"value": "ThingB"
}
}
],
"groups": [
{
"title": "Properties",
"kind": 1024,
"children": [
56
]
}
]
}
],
"groups": [
{
"title": "Classes",
"kind": 128,
"children": [
57
]
},
{
"title": "Interfaces",
"kind": 256,
"children": [
53,
55
]
}
]
},
{
"id": 21,
"name": "HorribleRecursiveTypeThatShouldNotBeUsedByAnyone",
Expand Down Expand Up @@ -884,7 +1062,8 @@
"children": [
28,
39,
43
43,
52
]
},
{
Expand Down

0 comments on commit 02fe2a7

Please sign in to comment.