Skip to content

Commit 34b7c33

Browse files
committed
Handle aliases in type parameters better
1 parent 9ab2b2e commit 34b7c33

File tree

6 files changed

+127
-13
lines changed

6 files changed

+127
-13
lines changed

src/parsers/common.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function getFullName(
3636

3737
const name = getTypeName(type, typeSymbol);
3838
const namespaces = typeSymbol ? getTypeSymbolNamespaces(typeSymbol) : getTypeNamespaces(type);
39-
const typeArguments = getTypeArguments(type, context);
39+
const typeArguments = getTypeArguments(type, typeNode, context);
4040

4141
if (name === undefined) {
4242
return undefined;
@@ -100,17 +100,26 @@ function getTypeName(type: ts.Type, typeSymbol: ts.Symbol | undefined): string |
100100
return typeName;
101101
}
102102

103-
function getTypeArguments(type: ts.Type, context: ParserContext): TypeArgument[] {
103+
function getTypeArguments(
104+
type: ts.Type,
105+
typeNode: ts.TypeNode | undefined,
106+
context: ParserContext,
107+
): TypeArgument[] {
104108
let typeArguments: TypeArgument[] = [];
105109

110+
const nodeTypeArguments =
111+
typeNode && ts.isTypeReferenceNode(typeNode)
112+
? ((typeNode as ts.TypeReferenceNode).typeArguments ?? [])
113+
: [];
114+
106115
if (type.aliasSymbol && !type.aliasTypeArguments) {
107116
typeArguments = [];
108117
} else {
109118
if ('target' in type) {
110119
typeArguments = context.checker
111120
.getTypeArguments(type as ts.TypeReference)
112121
?.map((arg, index) => {
113-
const parameterType = resolveType(arg, undefined, context);
122+
const parameterType = resolveType(arg, nodeTypeArguments[index], context);
114123
const equalToDefault = isGenericArgumentsSameAsDefault(type, index, context.checker);
115124

116125
return {
@@ -123,7 +132,7 @@ function getTypeArguments(type: ts.Type, context: ParserContext): TypeArgument[]
123132
if (!typeArguments.length) {
124133
typeArguments =
125134
type.aliasTypeArguments?.map((arg, index) => {
126-
const parameterType = resolveType(arg, undefined, context);
135+
const parameterType = resolveType(arg, nodeTypeArguments[index], context);
127136
resolveType(arg, undefined, context);
128137
const equalToDefault = isGenericArgumentsSameAsDefault(type, index, context.checker);
129138

src/parsers/objectParser.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import ts from 'typescript';
22
import { parseProperty } from './propertyParser';
33
import { ParserContext } from '../parser';
4-
import { ObjectNode } from '../models';
5-
import { getFullName } from './common';
4+
import { ObjectNode, TypeName } from '../models';
65

7-
export function parseObjectType(type: ts.Type, context: ParserContext): ObjectNode | undefined {
6+
export function parseObjectType(
7+
type: ts.Type,
8+
typeName: TypeName | undefined,
9+
context: ParserContext,
10+
): ObjectNode | undefined {
811
const { shouldInclude, shouldResolveObject, typeStack, includeExternalTypes } = context;
912

1013
const properties = type
1114
.getProperties()
1215
.filter((property) => includeExternalTypes || !isPropertyExternal(property));
1316

14-
const typeName = getFullName(type, undefined, context);
15-
1617
if (properties.length) {
1718
if (
1819
shouldResolveObject({

src/parsers/typeResolver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export function resolveType(
141141
return parseFunctionType(type, context)!;
142142
}
143143

144-
const objectType = parseObjectType(type, context);
144+
const objectType = parseObjectType(type, typeName, context);
145145
if (objectType) {
146146
return new IntersectionNode(typeName, memberTypes, objectType.properties);
147147
}
@@ -205,7 +205,7 @@ export function resolveType(
205205
return parseFunctionType(type, context)!;
206206
}
207207

208-
const objectType = parseObjectType(type, context);
208+
const objectType = parseObjectType(type, typeName, context);
209209
if (objectType) {
210210
return objectType;
211211
}

test/aliases-in-generics/input.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export function f(x: Params) {}
2+
3+
interface Params {
4+
a: Generic<Alias>;
5+
}
6+
7+
interface Generic<T> {
8+
value: T;
9+
}
10+
11+
interface Obj {
12+
x: number;
13+
}
14+
15+
type Alias = Obj;
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
{
2+
"name": "test/aliases-in-generics/input",
3+
"exports": [
4+
{
5+
"name": "f",
6+
"type": {
7+
"kind": "function",
8+
"typeName": {
9+
"name": "f"
10+
},
11+
"callSignatures": [
12+
{
13+
"parameters": [
14+
{
15+
"type": {
16+
"kind": "object",
17+
"typeName": {
18+
"name": "Params"
19+
},
20+
"properties": [
21+
{
22+
"name": "a",
23+
"type": {
24+
"kind": "object",
25+
"typeName": {
26+
"name": "Generic",
27+
"typeArguments": [
28+
{
29+
"type": {
30+
"kind": "object",
31+
"typeName": {
32+
"name": "Alias"
33+
},
34+
"properties": [
35+
{
36+
"name": "x",
37+
"type": {
38+
"kind": "intrinsic",
39+
"intrinsic": "number"
40+
},
41+
"optional": false
42+
}
43+
]
44+
},
45+
"equalToDefault": false
46+
}
47+
]
48+
},
49+
"properties": [
50+
{
51+
"name": "value",
52+
"type": {
53+
"kind": "object",
54+
"typeName": {
55+
"name": "Obj"
56+
},
57+
"properties": [
58+
{
59+
"name": "x",
60+
"type": {
61+
"kind": "intrinsic",
62+
"intrinsic": "number"
63+
},
64+
"optional": false
65+
}
66+
]
67+
},
68+
"optional": false
69+
}
70+
]
71+
},
72+
"optional": false
73+
}
74+
]
75+
},
76+
"name": "x",
77+
"optional": false
78+
}
79+
],
80+
"returnValueType": {
81+
"kind": "intrinsic",
82+
"intrinsic": "void"
83+
}
84+
}
85+
]
86+
}
87+
}
88+
]
89+
}

test/mapped-types/output.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"type": {
1616
"kind": "object",
1717
"typeName": {
18-
"name": "Partial",
18+
"name": "PartialType",
1919
"typeArguments": [
2020
{
2121
"type": {
@@ -118,7 +118,7 @@
118118
"type": {
119119
"kind": "object",
120120
"typeName": {
121-
"name": "Required",
121+
"name": "RequiredType",
122122
"typeArguments": [
123123
{
124124
"type": {

0 commit comments

Comments
 (0)