@@ -23,6 +23,7 @@ import {
23
23
flatMap ,
24
24
FunctionDeclaration ,
25
25
FunctionExpression ,
26
+ GenericType ,
26
27
GetAccessorDeclaration ,
27
28
getAllAccessorDeclarations ,
28
29
getCheckFlags ,
@@ -59,6 +60,8 @@ import {
59
60
isSetAccessorDeclaration ,
60
61
isStringLiteral ,
61
62
isTypeNode ,
63
+ isTypeReferenceNode ,
64
+ TypeReferenceNode ,
62
65
isTypeUsableAsPropertyName ,
63
66
isYieldExpression ,
64
67
LanguageServiceHost ,
@@ -595,7 +598,15 @@ function createTypeParameterName(index: number) {
595
598
596
599
/** @internal */
597
600
export function typeToAutoImportableTypeNode ( checker : TypeChecker , importAdder : ImportAdder , type : Type , contextNode : Node | undefined , scriptTarget : ScriptTarget , flags ?: NodeBuilderFlags , internalFlags ?: InternalNodeBuilderFlags , tracker ?: SymbolTracker ) : TypeNode | undefined {
598
- let typeNode = checker . typeToTypeNode ( type , contextNode , flags , internalFlags , tracker ) ;
601
+ const typeNode = checker . typeToTypeNode ( type , contextNode , flags , internalFlags , tracker ) ;
602
+ if ( ! typeNode ) {
603
+ return undefined ;
604
+ }
605
+ return typeNodeToAutoImportableTypeNode ( typeNode , importAdder , scriptTarget ) ;
606
+ }
607
+
608
+ /** @internal */
609
+ export function typeNodeToAutoImportableTypeNode ( typeNode : TypeNode , importAdder : ImportAdder , scriptTarget : ScriptTarget ) : TypeNode | undefined {
599
610
if ( typeNode && isImportTypeNode ( typeNode ) ) {
600
611
const importableReference = tryGetAutoImportableReferenceFromTypeNode ( typeNode , scriptTarget ) ;
601
612
if ( importableReference ) {
@@ -608,6 +619,43 @@ export function typeToAutoImportableTypeNode(checker: TypeChecker, importAdder:
608
619
return getSynthesizedDeepClone ( typeNode ) ;
609
620
}
610
621
622
+ function endOfRequiredTypeParameters ( checker : TypeChecker , type : GenericType , fullTypeArguments : readonly Type [ ] ) : number {
623
+ if ( fullTypeArguments !== type . typeArguments ! ) {
624
+ throw new Error ( 'fullTypeArguments should be set' )
625
+ }
626
+ const target = type . target ;
627
+ next_cutoff: for ( let cutoff = 0 ; cutoff < fullTypeArguments . length ; cutoff ++ ) {
628
+ const typeArguments = fullTypeArguments . slice ( 0 , cutoff ) ;
629
+ const filledIn = checker . fillMissingTypeArguments ( typeArguments , target . typeParameters , cutoff , /*isJavaScriptImplicitAny*/ false ) ;
630
+ for ( let i = 0 ; i < filledIn . length ; i ++ ) {
631
+ // If they don't match, then we haven't yet reached the right cutoff
632
+ if ( filledIn [ i ] !== fullTypeArguments [ i ] ) continue next_cutoff;
633
+ }
634
+ return cutoff ;
635
+ }
636
+ // If we make it all the way here, all the type arguments are required.
637
+ return fullTypeArguments . length ;
638
+ }
639
+
640
+ export function typeToMinimizedReferenceType ( checker : TypeChecker , type : Type , contextNode : Node | undefined , flags ?: NodeBuilderFlags , internalFlags ?: InternalNodeBuilderFlags , tracker ?: SymbolTracker ) : TypeNode | undefined {
641
+ const typeNode = checker . typeToTypeNode ( type , contextNode , flags , internalFlags , tracker ) ;
642
+ if ( ! typeNode ) {
643
+ return undefined ;
644
+ }
645
+ if ( isTypeReferenceNode ( typeNode ) ) {
646
+ const genericType = type as GenericType ;
647
+ if ( genericType . typeArguments ) {
648
+ const cutoff = endOfRequiredTypeParameters ( checker , genericType , genericType . typeArguments ) ;
649
+ if ( cutoff !== undefined && typeNode . typeArguments ) {
650
+ // Looks like the wrong way to do this. What APIs should I use here?
651
+ ( typeNode as any ) . typeArguments = typeNode . typeArguments . slice ( 0 , cutoff ) ;
652
+ }
653
+ }
654
+
655
+ }
656
+ return typeNode ;
657
+ }
658
+
611
659
/** @internal */
612
660
export function typePredicateToAutoImportableTypeNode ( checker : TypeChecker , importAdder : ImportAdder , typePredicate : TypePredicate , contextNode : Node | undefined , scriptTarget : ScriptTarget , flags ?: NodeBuilderFlags , internalFlags ?: InternalNodeBuilderFlags , tracker ?: SymbolTracker ) : TypeNode | undefined {
613
661
let typePredicateNode = checker . typePredicateToTypePredicateNode ( typePredicate , contextNode , flags , internalFlags , tracker ) ;
0 commit comments