/
types.ts
51 lines (43 loc) · 1.86 KB
/
types.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import * as ts from 'typescript';
/**
* Returns the type parameters of a given type.
* @param type The type whos type parameters are wanted.
* @returns The type parameters of the type. An empty array if the type has no type parameters.
*/
export function getTypeParametersOfType(type: ts.Type): ReadonlyArray<ts.TypeParameterDeclaration> {
const declarations = type.getSymbol()?.getDeclarations() ?? [];
for (const declaration of declarations) {
if ((ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) &&
declaration.typeParameters) {
return declaration.typeParameters;
}
}
return [];
}
/**
* Returns a list of type arguments. If a type parameter has no corresponding type argument, the default type
* for that type parameter is used as the type argument.
* @param typeParams The type parameters for which the type arguments are wanted.
* @param typeArguments The type arguments as provided in the declaration.
* @returns The complete list of type arguments with possible default values if type arguments are missing.
*/
export function getTypeArgumentsWithDefaults(
typeParams: ts.TypeParameterDeclaration[],
typeArguments?: ReadonlyArray<ts.TypeNode>
): ReadonlyArray<ts.TypeNode> {
if (!typeArguments || typeParams.length > typeArguments.length) {
const typeArgumentsWithDefaults = new Array<ts.TypeNode>();
for (let i = 0; i < typeParams.length; ++i) {
if (typeArguments && typeArguments[i]) {
typeArgumentsWithDefaults.push(typeArguments[i]);
} else {
const defaultType = typeParams[i].default;
if (defaultType) {
typeArgumentsWithDefaults.push(defaultType);
}
}
}
return typeArgumentsWithDefaults;
}
return typeArguments;
}