@travetto/transformer 3.0.0-rc.2 → 3.0.0-rc.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -12
- package/__index__.ts +15 -0
- package/package.json +13 -6
- package/src/importer.ts +120 -35
- package/src/manager.ts +74 -0
- package/src/register.ts +40 -11
- package/src/resolver/builder.ts +61 -53
- package/src/resolver/cache.ts +2 -2
- package/src/resolver/coerce.ts +103 -0
- package/src/resolver/service.ts +48 -9
- package/src/resolver/types.ts +7 -4
- package/src/state.ts +85 -71
- package/src/types/shared.ts +1 -1
- package/src/types/visitor.ts +7 -5
- package/src/util/core.ts +8 -6
- package/src/util/declaration.ts +3 -3
- package/src/util/decorator.ts +1 -1
- package/src/util/doc.ts +1 -1
- package/src/util/import.ts +17 -10
- package/src/util/literal.ts +3 -2
- package/src/util/log.ts +4 -5
- package/src/util/system.ts +31 -0
- package/src/visitor.ts +13 -33
- package/index.ts +0 -7
- package/src/util/index.ts +0 -6
- package/test-support/util.ts +0 -57
package/src/resolver/builder.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/* eslint-disable no-bitwise */
|
|
2
|
-
import
|
|
3
|
-
import { dirname } from 'path';
|
|
2
|
+
import ts from 'typescript';
|
|
4
3
|
|
|
5
|
-
import {
|
|
6
|
-
import { Util } from '@travetto/base';
|
|
4
|
+
import { path } from '@travetto/manifest';
|
|
7
5
|
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import { DocUtil } from '../util/doc';
|
|
7
|
+
import { CoreUtil } from '../util/core';
|
|
8
|
+
import { DeclarationUtil } from '../util/declaration';
|
|
9
|
+
import { LiteralUtil } from '../util/literal';
|
|
10
|
+
|
|
11
|
+
import { Type, AnyType, UnionType, TransformResolver } from './types';
|
|
12
|
+
import { CoerceUtil } from './coerce';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* List of global types that can be parameterized
|
|
@@ -35,7 +38,7 @@ type Category = 'void' | 'undefined' | 'concrete' | 'unknown' | 'tuple' | 'shape
|
|
|
35
38
|
/**
|
|
36
39
|
* Type categorizer, input for builder
|
|
37
40
|
*/
|
|
38
|
-
export function TypeCategorize(
|
|
41
|
+
export function TypeCategorize(resolver: TransformResolver, type: ts.Type): { category: Category, type: ts.Type } {
|
|
39
42
|
const flags = type.getFlags();
|
|
40
43
|
const objectFlags = DeclarationUtil.getObjectFlags(type) ?? 0;
|
|
41
44
|
|
|
@@ -62,9 +65,10 @@ export function TypeCategorize(checker: ts.TypeChecker, type: ts.Type): { catego
|
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
const source = DeclarationUtil.getPrimaryDeclarationNode(resolvedType).getSourceFile();
|
|
65
|
-
|
|
68
|
+
const sourceFile = source.fileName;
|
|
69
|
+
if (sourceFile?.includes('@types/node/globals') || sourceFile?.includes('typescript/lib')) {
|
|
66
70
|
return { category: 'literal', type };
|
|
67
|
-
} else if (
|
|
71
|
+
} else if (sourceFile?.endsWith('.d.ts') && !resolver.isKnownFile(sourceFile)) {
|
|
68
72
|
return { category: 'unknown', type };
|
|
69
73
|
} else if (!resolvedType.isClass()) { // Not a real type
|
|
70
74
|
return { category: 'shape', type: resolvedType };
|
|
@@ -93,32 +97,32 @@ export function TypeCategorize(checker: ts.TypeChecker, type: ts.Type): { catego
|
|
|
93
97
|
*/
|
|
94
98
|
export const TypeBuilder: {
|
|
95
99
|
[K in Category]: {
|
|
96
|
-
build(
|
|
100
|
+
build(resolver: TransformResolver, type: ts.Type, alias?: ts.Symbol): AnyType | undefined;
|
|
97
101
|
finalize?(type: Type<K>): AnyType;
|
|
98
102
|
}
|
|
99
103
|
} = {
|
|
100
104
|
unknown: {
|
|
101
|
-
build: (
|
|
105
|
+
build: (resolver, type) => undefined
|
|
102
106
|
},
|
|
103
107
|
undefined: {
|
|
104
|
-
build: (
|
|
108
|
+
build: (resolver, type) => ({ key: 'literal', name: 'undefined', ctor: undefined })
|
|
105
109
|
},
|
|
106
110
|
void: {
|
|
107
|
-
build: (
|
|
111
|
+
build: (resolver, type) => ({ key: 'literal', name: 'void', ctor: undefined })
|
|
108
112
|
},
|
|
109
113
|
tuple: {
|
|
110
|
-
build: (
|
|
114
|
+
build: (resolver, type) => ({ key: 'tuple', tsTupleTypes: resolver.getAllTypeArguments(type), subTypes: [] })
|
|
111
115
|
},
|
|
112
116
|
literal: {
|
|
113
|
-
build: (
|
|
117
|
+
build: (resolver, type) => {
|
|
114
118
|
// Handle void/undefined
|
|
115
|
-
const name =
|
|
119
|
+
const name = resolver.getTypeAsString(type) ?? '';
|
|
116
120
|
const complexName = CoreUtil.getSymbol(type)?.getName() ?? '';
|
|
117
121
|
|
|
118
122
|
if (name in GLOBAL_SIMPLE) {
|
|
119
123
|
const cons = GLOBAL_SIMPLE[name];
|
|
120
124
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
121
|
-
const ret = LiteralUtil.isLiteralType(type) ?
|
|
125
|
+
const ret = LiteralUtil.isLiteralType(type) ? CoerceUtil.coerce(type.value, cons as typeof String, false) :
|
|
122
126
|
undefined;
|
|
123
127
|
|
|
124
128
|
return {
|
|
@@ -133,23 +137,21 @@ export const TypeBuilder: {
|
|
|
133
137
|
key: 'literal',
|
|
134
138
|
name: cons.name,
|
|
135
139
|
ctor: cons,
|
|
136
|
-
tsTypeArguments:
|
|
140
|
+
tsTypeArguments: resolver.getAllTypeArguments(type)
|
|
137
141
|
};
|
|
138
142
|
}
|
|
139
143
|
}
|
|
140
144
|
},
|
|
141
145
|
external: {
|
|
142
|
-
build: (
|
|
143
|
-
const source = DeclarationUtil.getPrimaryDeclarationNode(type).getSourceFile();
|
|
146
|
+
build: (resolver, type) => {
|
|
144
147
|
const name = CoreUtil.getSymbol(type)?.getName();
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
};
|
|
148
|
+
const importName = resolver.getTypeImportName(type)!;
|
|
149
|
+
const tsTypeArguments = resolver.getAllTypeArguments(type);
|
|
150
|
+
return { key: 'external', name, importName, tsTypeArguments };
|
|
149
151
|
}
|
|
150
152
|
},
|
|
151
153
|
union: {
|
|
152
|
-
build: (
|
|
154
|
+
build: (resolver, uType: ts.UnionType) => {
|
|
153
155
|
let undefinable = false;
|
|
154
156
|
let nullable = false;
|
|
155
157
|
const remainder = uType.types.filter(ut => {
|
|
@@ -175,50 +177,56 @@ export const TypeBuilder: {
|
|
|
175
177
|
}
|
|
176
178
|
},
|
|
177
179
|
shape: {
|
|
178
|
-
build: (
|
|
179
|
-
const
|
|
180
|
-
const name = CoreUtil.getSymbol(alias ?? type);
|
|
181
|
-
const
|
|
182
|
-
|
|
180
|
+
build: (resolver, type, alias?) => {
|
|
181
|
+
const tsFieldTypes: Record<string, ts.Type> = {};
|
|
182
|
+
const name = CoreUtil.getSymbol(alias ?? type)?.getName();
|
|
183
|
+
const importName = resolver.getTypeImportName(type) ?? '<unknown>';
|
|
184
|
+
const tsTypeArguments = resolver.getAllTypeArguments(type);
|
|
185
|
+
const props = resolver.getPropertiesOfType(type);
|
|
186
|
+
if (props.length === 0) {
|
|
187
|
+
return { key: 'unknown', name, importName };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
for (const member of props) {
|
|
183
191
|
const dec = DeclarationUtil.getPrimaryDeclarationNode(member);
|
|
184
192
|
if (DeclarationUtil.isPublic(dec)) { // If public
|
|
185
|
-
const memberType =
|
|
186
|
-
if (
|
|
187
|
-
|
|
193
|
+
const memberType = resolver.getType(dec);
|
|
194
|
+
if (
|
|
195
|
+
!member.getName().includes('@') && // if not a symbol
|
|
196
|
+
!memberType.getCallSignatures().length // if not a function
|
|
197
|
+
) {
|
|
198
|
+
tsFieldTypes[member.getName()] = memberType;
|
|
188
199
|
}
|
|
189
200
|
}
|
|
190
201
|
}
|
|
191
|
-
return {
|
|
192
|
-
key: 'shape', name: name?.getName(),
|
|
193
|
-
source: source?.fileName,
|
|
194
|
-
tsFieldTypes: fieldNodes,
|
|
195
|
-
tsTypeArguments: checker.getAllTypeArguments(type),
|
|
196
|
-
fieldTypes: {}
|
|
197
|
-
};
|
|
202
|
+
return { key: 'shape', name, importName, tsFieldTypes, tsTypeArguments, fieldTypes: {} };
|
|
198
203
|
}
|
|
199
204
|
},
|
|
200
205
|
concrete: {
|
|
201
|
-
build: (
|
|
206
|
+
build: (resolver, type) => {
|
|
202
207
|
const [tag] = DocUtil.readDocTag(type, 'concrete');
|
|
203
208
|
if (tag) {
|
|
204
209
|
// eslint-disable-next-line prefer-const
|
|
205
|
-
let [
|
|
210
|
+
let [importName, name] = tag.split(':');
|
|
206
211
|
if (!name) {
|
|
207
|
-
name =
|
|
208
|
-
|
|
212
|
+
name = importName;
|
|
213
|
+
importName = '.';
|
|
209
214
|
}
|
|
210
215
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
216
|
+
// Resolving relative to source file
|
|
217
|
+
if (importName.startsWith('.')) {
|
|
218
|
+
const rawSourceFile: string = DeclarationUtil.getDeclarations(type)
|
|
219
|
+
?.find(x => ts.getAllJSDocTags(x, (t): t is ts.JSDocTag => t.tagName.getText() === 'concrete').length)
|
|
220
|
+
?.getSourceFile().fileName ?? '';
|
|
214
221
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
222
|
+
if (importName === '.') {
|
|
223
|
+
importName = resolver.getFileImportName(rawSourceFile);
|
|
224
|
+
} else {
|
|
225
|
+
const base = path.dirname(rawSourceFile);
|
|
226
|
+
importName = resolver.getFileImportName(path.resolve(base, importName));
|
|
227
|
+
}
|
|
219
228
|
}
|
|
220
|
-
|
|
221
|
-
return { key: 'external', name, source: ext === 'node' ? source : PathUtil.resolveUnix(sourceFile, source) };
|
|
229
|
+
return { key: 'external', name, importName };
|
|
222
230
|
}
|
|
223
231
|
}
|
|
224
232
|
}
|
package/src/resolver/cache.ts
CHANGED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const REGEX_PAT = /[\/](.*)[\/](i|g|m|s)?/;
|
|
2
|
+
|
|
3
|
+
export class CoerceUtil {
|
|
4
|
+
/**
|
|
5
|
+
* Is a value a plain JS object, created using {}
|
|
6
|
+
*/
|
|
7
|
+
static #isPlainObject(obj: unknown): obj is Record<string, unknown> {
|
|
8
|
+
return typeof obj === 'object' // separate from primitives
|
|
9
|
+
&& obj !== undefined
|
|
10
|
+
&& obj !== null // is obvious
|
|
11
|
+
&& obj.constructor === Object // separate instances (Array, DOM, ...)
|
|
12
|
+
&& Object.prototype.toString.call(obj) === '[object Object]'; // separate build-in like Math
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create regex from string, including flags
|
|
17
|
+
*/
|
|
18
|
+
static #toRegex(input: string | RegExp): RegExp {
|
|
19
|
+
if (input instanceof RegExp) {
|
|
20
|
+
return input;
|
|
21
|
+
} else if (REGEX_PAT.test(input)) {
|
|
22
|
+
const [, pat, mod] = input.match(REGEX_PAT) ?? [];
|
|
23
|
+
return new RegExp(pat, mod);
|
|
24
|
+
} else {
|
|
25
|
+
return new RegExp(input);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Coerce an input of any type to the class provided
|
|
31
|
+
* @param input Input value
|
|
32
|
+
* @param type Class to coerce to (String, Boolean, Number, Date, RegEx, Object)
|
|
33
|
+
* @param strict Should a failure to coerce throw an error?
|
|
34
|
+
*/
|
|
35
|
+
static coerce(input: unknown, type: typeof String, strict?: boolean): string;
|
|
36
|
+
static coerce(input: unknown, type: typeof Number, strict?: boolean): number;
|
|
37
|
+
static coerce(input: unknown, type: typeof Boolean, strict?: boolean): boolean;
|
|
38
|
+
static coerce(input: unknown, type: typeof Date, strict?: boolean): Date;
|
|
39
|
+
static coerce(input: unknown, type: typeof RegExp, strict?: boolean): RegExp;
|
|
40
|
+
static coerce(input: unknown, type: Function, strict = true): unknown {
|
|
41
|
+
// Do nothing
|
|
42
|
+
if (input === null || input === undefined) {
|
|
43
|
+
return input;
|
|
44
|
+
} else if (!strict && type !== String && input === '') {
|
|
45
|
+
return undefined; // treat empty string as undefined for non-strings in non-strict mode
|
|
46
|
+
} else if (type && input instanceof type) {
|
|
47
|
+
return input;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
switch (type) {
|
|
51
|
+
case Date: {
|
|
52
|
+
const res = typeof input === 'number' || /^[-]?\d+$/.test(`${input}`) ?
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
54
|
+
new Date(parseInt(input as string, 10)) : new Date(input as Date);
|
|
55
|
+
if (strict && Number.isNaN(res.getTime())) {
|
|
56
|
+
throw new Error(`Invalid date value: ${input}`);
|
|
57
|
+
}
|
|
58
|
+
return res;
|
|
59
|
+
}
|
|
60
|
+
case Number: {
|
|
61
|
+
const res = `${input}`.includes('.') ? parseFloat(`${input}`) : parseInt(`${input}`, 10);
|
|
62
|
+
if (strict && Number.isNaN(res)) {
|
|
63
|
+
throw new Error(`Invalid numeric value: ${input}`);
|
|
64
|
+
}
|
|
65
|
+
return res;
|
|
66
|
+
}
|
|
67
|
+
case Boolean: {
|
|
68
|
+
const match = `${input}`.match(/^((?<TRUE>true|yes|1|on)|false|no|off|0)$/i);
|
|
69
|
+
if (strict && !match) {
|
|
70
|
+
throw new Error(`Invalid boolean value: ${input}`);
|
|
71
|
+
}
|
|
72
|
+
return !!match?.groups?.TRUE;
|
|
73
|
+
}
|
|
74
|
+
case RegExp: {
|
|
75
|
+
if (typeof input === 'string') {
|
|
76
|
+
try {
|
|
77
|
+
return this.#toRegex(input);
|
|
78
|
+
} catch {
|
|
79
|
+
if (strict) {
|
|
80
|
+
throw new Error(`Invalid regex: ${input}`);
|
|
81
|
+
} else {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} else if (strict) {
|
|
86
|
+
throw new Error('Invalid regex type');
|
|
87
|
+
} else {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
case Object: {
|
|
92
|
+
if (!strict || this.#isPlainObject(input)) {
|
|
93
|
+
return input;
|
|
94
|
+
} else {
|
|
95
|
+
throw new Error('Invalid object type');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
case undefined:
|
|
99
|
+
case String: return `${input}`;
|
|
100
|
+
}
|
|
101
|
+
throw new Error(`Unknown type ${type.name}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
package/src/resolver/service.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ts from 'typescript';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ManifestIndex, path } from '@travetto/manifest';
|
|
4
|
+
|
|
5
|
+
import type { AnyType, TransformResolver } from './types';
|
|
4
6
|
import { TypeCategorize, TypeBuilder } from './builder';
|
|
5
7
|
import { VisitCache } from './cache';
|
|
6
|
-
import { DocUtil } from '../util';
|
|
8
|
+
import { DocUtil } from '../util/doc';
|
|
9
|
+
import { DeclarationUtil } from '../util/declaration';
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
|
-
*
|
|
12
|
+
* Implementation of TransformResolver
|
|
10
13
|
*/
|
|
11
|
-
export class
|
|
14
|
+
export class SimpleResolver implements TransformResolver {
|
|
12
15
|
#tsChecker: ts.TypeChecker;
|
|
16
|
+
#manifestIndex: ManifestIndex;
|
|
13
17
|
|
|
14
|
-
constructor(tsChecker: ts.TypeChecker) {
|
|
18
|
+
constructor(tsChecker: ts.TypeChecker, manifestIndex: ManifestIndex) {
|
|
15
19
|
this.#tsChecker = tsChecker;
|
|
20
|
+
this.#manifestIndex = manifestIndex;
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
/**
|
|
@@ -23,6 +28,40 @@ export class TypeResolver implements Checker {
|
|
|
23
28
|
return this.#tsChecker;
|
|
24
29
|
}
|
|
25
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Resolve an import name (e.g. @module/path/file) for a file
|
|
33
|
+
*/
|
|
34
|
+
getFileImportName(file: string, removeExt?: boolean): string {
|
|
35
|
+
let sourceFile = path.toPosix(file);
|
|
36
|
+
|
|
37
|
+
if (!sourceFile.endsWith('.js') && !sourceFile.endsWith('.ts')) {
|
|
38
|
+
sourceFile = `${sourceFile}.ts`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const imp =
|
|
42
|
+
this.#manifestIndex.getEntry(/[.]ts$/.test(sourceFile) ? sourceFile : `${sourceFile}.js`)?.import ??
|
|
43
|
+
this.#manifestIndex.getFromImport(sourceFile.replace(/^.*node_modules\//, '').replace(/[.]ts$/, ''))?.import ??
|
|
44
|
+
file;
|
|
45
|
+
|
|
46
|
+
return removeExt ? imp.replace(/[.]js$/, '') : imp;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolve an import name (e.g. @module/path/file) for a type
|
|
51
|
+
*/
|
|
52
|
+
getTypeImportName(type: ts.Type, removeExt?: boolean): string | undefined {
|
|
53
|
+
const ogSource = DeclarationUtil.getPrimaryDeclarationNode(type)?.getSourceFile()?.fileName;
|
|
54
|
+
return ogSource ? this.getFileImportName(ogSource, removeExt) : undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Is the file/import known to the index, helpful for determine ownership
|
|
59
|
+
*/
|
|
60
|
+
isKnownFile(fileOrImport: string): boolean {
|
|
61
|
+
return (this.#manifestIndex.getFromSource(fileOrImport) !== undefined) ||
|
|
62
|
+
(this.#manifestIndex.getFromImport(fileOrImport) !== undefined);
|
|
63
|
+
}
|
|
64
|
+
|
|
26
65
|
/**
|
|
27
66
|
* Get type from element
|
|
28
67
|
* @param el
|
|
@@ -65,7 +104,7 @@ export class TypeResolver implements Checker {
|
|
|
65
104
|
/**
|
|
66
105
|
* Resolve an `AnyType` from a `ts.Type` or a `ts.Node`
|
|
67
106
|
*/
|
|
68
|
-
resolveType(node: ts.Type | ts.Node): AnyType {
|
|
107
|
+
resolveType(node: ts.Type | ts.Node, importName: string): AnyType {
|
|
69
108
|
const visited = new VisitCache();
|
|
70
109
|
const resolve = (resType: ts.Type, alias?: ts.Symbol, depth = 0): AnyType => {
|
|
71
110
|
|
|
@@ -73,7 +112,7 @@ export class TypeResolver implements Checker {
|
|
|
73
112
|
throw new Error('Object structure too nested');
|
|
74
113
|
}
|
|
75
114
|
|
|
76
|
-
const { category, type } = TypeCategorize(this
|
|
115
|
+
const { category, type } = TypeCategorize(this, resType);
|
|
77
116
|
const { build, finalize } = TypeBuilder[category];
|
|
78
117
|
|
|
79
118
|
let result = build(this, type, alias);
|
|
@@ -117,7 +156,7 @@ export class TypeResolver implements Checker {
|
|
|
117
156
|
if (!(err instanceof Error)) {
|
|
118
157
|
throw err;
|
|
119
158
|
}
|
|
120
|
-
console.error(
|
|
159
|
+
console.error(`Unable to resolve type in ${importName}`, err.stack);
|
|
121
160
|
return { key: 'literal', ctor: Object, name: 'object' };
|
|
122
161
|
}
|
|
123
162
|
}
|
package/src/resolver/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type ts from 'typescript';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Base type for a simplistic type structure
|
|
@@ -37,7 +37,7 @@ export interface ExternalType extends Type<'external'> {
|
|
|
37
37
|
/**
|
|
38
38
|
* Location the type came from, for class references
|
|
39
39
|
*/
|
|
40
|
-
|
|
40
|
+
importName: string;
|
|
41
41
|
/**
|
|
42
42
|
* Type arguments
|
|
43
43
|
*/
|
|
@@ -55,7 +55,7 @@ export interface ShapeType extends Type<'shape'> {
|
|
|
55
55
|
/**
|
|
56
56
|
* Location the type came from, for class references
|
|
57
57
|
*/
|
|
58
|
-
|
|
58
|
+
importName: string;
|
|
59
59
|
/**
|
|
60
60
|
* Does not include methods, used for shapes not concrete types
|
|
61
61
|
*/
|
|
@@ -151,7 +151,10 @@ export type AnyType = TupleType | ShapeType | UnionType | LiteralType | External
|
|
|
151
151
|
/**
|
|
152
152
|
* Simple interface for checked methods
|
|
153
153
|
*/
|
|
154
|
-
export interface
|
|
154
|
+
export interface TransformResolver {
|
|
155
|
+
isKnownFile(file: string): boolean;
|
|
156
|
+
getFileImportName(file: string, removeExt?: boolean): string;
|
|
157
|
+
getTypeImportName(type: ts.Type, removeExt?: boolean): string | undefined;
|
|
155
158
|
getAllTypeArguments(type: ts.Type): ts.Type[];
|
|
156
159
|
getPropertiesOfType(type: ts.Type): ts.Symbol[];
|
|
157
160
|
getTypeAsString(type: ts.Type): string | undefined;
|