mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-23 07:07:09 -05:00
Drop unnecessary type arguments in the isolated declarations quick fix (#59665)
Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
@@ -4,8 +4,9 @@ import {
|
||||
createImportAdder,
|
||||
eachDiagnostic,
|
||||
registerCodeFix,
|
||||
typeNodeToAutoImportableTypeNode,
|
||||
typePredicateToAutoImportableTypeNode,
|
||||
typeToAutoImportableTypeNode,
|
||||
typeToMinimizedReferenceType,
|
||||
} from "../_namespaces/ts.codefix.js";
|
||||
import {
|
||||
ArrayBindingPattern,
|
||||
@@ -1096,9 +1097,9 @@ function withContext<T>(
|
||||
return emptyInferenceResult;
|
||||
}
|
||||
|
||||
function typeToTypeNode(type: Type, enclosingDeclaration: Node, flags = NodeBuilderFlags.None) {
|
||||
function typeToTypeNode(type: Type, enclosingDeclaration: Node, flags = NodeBuilderFlags.None): TypeNode | undefined {
|
||||
let isTruncated = false;
|
||||
const result = typeToAutoImportableTypeNode(typeChecker, importAdder, type, enclosingDeclaration, scriptTarget, declarationEmitNodeBuilderFlags | flags, declarationEmitInternalNodeBuilderFlags, {
|
||||
const minimizedTypeNode = typeToMinimizedReferenceType(typeChecker, type, enclosingDeclaration, declarationEmitNodeBuilderFlags | flags, declarationEmitInternalNodeBuilderFlags, {
|
||||
moduleResolverHost: program,
|
||||
trackSymbol() {
|
||||
return true;
|
||||
@@ -1107,6 +1108,10 @@ function withContext<T>(
|
||||
isTruncated = true;
|
||||
},
|
||||
});
|
||||
if (!minimizedTypeNode) {
|
||||
return undefined;
|
||||
}
|
||||
const result = typeNodeToAutoImportableTypeNode(minimizedTypeNode, importAdder, scriptTarget);
|
||||
return isTruncated ? factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) : result;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
flatMap,
|
||||
FunctionDeclaration,
|
||||
FunctionExpression,
|
||||
GenericType,
|
||||
GetAccessorDeclaration,
|
||||
getAllAccessorDeclarations,
|
||||
getCheckFlags,
|
||||
@@ -59,6 +60,7 @@ import {
|
||||
isSetAccessorDeclaration,
|
||||
isStringLiteral,
|
||||
isTypeNode,
|
||||
isTypeReferenceNode,
|
||||
isTypeUsableAsPropertyName,
|
||||
isYieldExpression,
|
||||
LanguageServiceHost,
|
||||
@@ -595,7 +597,15 @@ function createTypeParameterName(index: number) {
|
||||
|
||||
/** @internal */
|
||||
export function typeToAutoImportableTypeNode(checker: TypeChecker, importAdder: ImportAdder, type: Type, contextNode: Node | undefined, scriptTarget: ScriptTarget, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined {
|
||||
let typeNode = checker.typeToTypeNode(type, contextNode, flags, internalFlags, tracker);
|
||||
const typeNode = checker.typeToTypeNode(type, contextNode, flags, internalFlags, tracker);
|
||||
if (!typeNode) {
|
||||
return undefined;
|
||||
}
|
||||
return typeNodeToAutoImportableTypeNode(typeNode, importAdder, scriptTarget);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function typeNodeToAutoImportableTypeNode(typeNode: TypeNode, importAdder: ImportAdder, scriptTarget: ScriptTarget): TypeNode | undefined {
|
||||
if (typeNode && isImportTypeNode(typeNode)) {
|
||||
const importableReference = tryGetAutoImportableReferenceFromTypeNode(typeNode, scriptTarget);
|
||||
if (importableReference) {
|
||||
@@ -608,6 +618,40 @@ export function typeToAutoImportableTypeNode(checker: TypeChecker, importAdder:
|
||||
return getSynthesizedDeepClone(typeNode);
|
||||
}
|
||||
|
||||
function endOfRequiredTypeParameters(checker: TypeChecker, type: GenericType): number {
|
||||
Debug.assert(type.typeArguments);
|
||||
const fullTypeArguments = type.typeArguments;
|
||||
const target = type.target;
|
||||
for (let cutoff = 0; cutoff < fullTypeArguments.length; cutoff++) {
|
||||
const typeArguments = fullTypeArguments.slice(0, cutoff);
|
||||
const filledIn = checker.fillMissingTypeArguments(typeArguments, target.typeParameters, cutoff, /*isJavaScriptImplicitAny*/ false);
|
||||
if (filledIn.every((fill, i) => fill === fullTypeArguments[i])) {
|
||||
return cutoff;
|
||||
}
|
||||
}
|
||||
// If we make it all the way here, all the type arguments are required.
|
||||
return fullTypeArguments.length;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function typeToMinimizedReferenceType(checker: TypeChecker, type: Type, contextNode: Node | undefined, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined {
|
||||
let typeNode = checker.typeToTypeNode(type, contextNode, flags, internalFlags, tracker);
|
||||
if (!typeNode) {
|
||||
return undefined;
|
||||
}
|
||||
if (isTypeReferenceNode(typeNode)) {
|
||||
const genericType = type as GenericType;
|
||||
if (genericType.typeArguments && typeNode.typeArguments) {
|
||||
const cutoff = endOfRequiredTypeParameters(checker, genericType);
|
||||
if (cutoff < typeNode.typeArguments.length) {
|
||||
const newTypeArguments = factory.createNodeArray(typeNode.typeArguments.slice(0, cutoff));
|
||||
typeNode = factory.updateTypeReferenceNode(typeNode, typeNode.typeName, newTypeArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
return typeNode;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function typePredicateToAutoImportableTypeNode(checker: TypeChecker, importAdder: ImportAdder, typePredicate: TypePredicate, contextNode: Node | undefined, scriptTarget: ScriptTarget, flags?: NodeBuilderFlags, internalFlags?: InternalNodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined {
|
||||
let typePredicateNode = checker.typePredicateToTypePredicateNode(typePredicate, contextNode, flags, internalFlags, tracker);
|
||||
|
||||
Reference in New Issue
Block a user