@@ -72,8 +72,18 @@ function innerResolveTypeElements(
72
72
if ( resolved ) {
73
73
return resolveTypeElements ( ctx , resolved )
74
74
} else {
75
- // TODO Pick / Omit
76
- ctx . error ( `Failed to resolved type reference` , node )
75
+ const typeName = getReferenceName ( node )
76
+ if (
77
+ typeof typeName === 'string' &&
78
+ // @ts -ignore
79
+ SupportedBuiltinsSet . has ( typeName )
80
+ ) {
81
+ return resolveBuiltin ( ctx , node , typeName as any )
82
+ }
83
+ ctx . error (
84
+ `Failed to resolved type reference, or unsupported built-in utlility type.` ,
85
+ node
86
+ )
77
87
}
78
88
}
79
89
case 'TSUnionType' :
@@ -290,24 +300,79 @@ function resolveTemplateKeys(
290
300
return res
291
301
}
292
302
303
+ const SupportedBuiltinsSet = new Set ( [
304
+ 'Partial' ,
305
+ 'Required' ,
306
+ 'Readonly' ,
307
+ 'Pick' ,
308
+ 'Omit'
309
+ ] as const )
310
+
311
+ type GetSetType < T > = T extends Set < infer V > ? V : never
312
+
313
+ function resolveBuiltin (
314
+ ctx : ScriptCompileContext ,
315
+ node : TSTypeReference | TSExpressionWithTypeArguments ,
316
+ name : GetSetType < typeof SupportedBuiltinsSet >
317
+ ) : ResolvedElements {
318
+ const t = resolveTypeElements ( ctx , node . typeParameters ! . params [ 0 ] )
319
+ switch ( name ) {
320
+ case 'Partial' :
321
+ case 'Required' :
322
+ case 'Readonly' :
323
+ return t
324
+ case 'Pick' : {
325
+ const picked = resolveStringType ( ctx , node . typeParameters ! . params [ 1 ] )
326
+ const res : ResolvedElements = { }
327
+ if ( t . __callSignatures ) addCallSignature ( res , t . __callSignatures )
328
+ for ( const key of picked ) {
329
+ res [ key ] = t [ key ]
330
+ }
331
+ return res
332
+ }
333
+ case 'Omit' :
334
+ const omitted = resolveStringType ( ctx , node . typeParameters ! . params [ 1 ] )
335
+ const res : ResolvedElements = { }
336
+ if ( t . __callSignatures ) addCallSignature ( res , t . __callSignatures )
337
+ for ( const key in t ) {
338
+ if ( ! omitted . includes ( key ) ) {
339
+ res [ key ] = t [ key ]
340
+ }
341
+ }
342
+ return res
343
+ }
344
+ }
345
+
293
346
function resolveTypeReference (
294
347
ctx : ScriptCompileContext ,
295
348
node : TSTypeReference | TSExpressionWithTypeArguments ,
296
349
scope = getRootScope ( ctx )
297
350
) : Node | undefined {
298
- const ref = node . type === 'TSTypeReference' ? node . typeName : node . expression
299
- if ( ref . type === 'Identifier ' ) {
300
- if ( scope . imports [ ref . name ] ) {
351
+ const name = getReferenceName ( node )
352
+ if ( typeof name === 'string ' ) {
353
+ if ( scope . imports [ name ] ) {
301
354
// TODO external import
302
- } else if ( scope . types [ ref . name ] ) {
303
- return scope . types [ ref . name ]
355
+ } else if ( scope . types [ name ] ) {
356
+ return scope . types [ name ]
304
357
}
305
358
} else {
306
359
// TODO qualified name, e.g. Foo.Bar
307
360
// return resolveTypeReference()
308
361
}
309
362
}
310
363
364
+ function getReferenceName (
365
+ node : TSTypeReference | TSExpressionWithTypeArguments
366
+ ) : string | string [ ] {
367
+ const ref = node . type === 'TSTypeReference' ? node . typeName : node . expression
368
+ if ( ref . type === 'Identifier' ) {
369
+ return ref . name
370
+ } else {
371
+ // TODO qualified name, e.g. Foo.Bar
372
+ return [ ]
373
+ }
374
+ }
375
+
311
376
function getRootScope ( ctx : ScriptCompileContext ) : TypeScope {
312
377
if ( ctx . scope ) {
313
378
return ctx . scope
0 commit comments