mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
feat(25770): add Quick Fix to convert LiteralType to MappedType (#40226)
This commit is contained in:
@@ -5335,6 +5335,10 @@
|
||||
"category": "Message",
|
||||
"code": 95002
|
||||
},
|
||||
"Convert '{0}' to '{1} in {0}'": {
|
||||
"category": "Message",
|
||||
"code": 95003
|
||||
},
|
||||
"Extract to {0} in {1}": {
|
||||
"category": "Message",
|
||||
"code": 95004
|
||||
@@ -5403,6 +5407,10 @@
|
||||
"category": "Message",
|
||||
"code": 95020
|
||||
},
|
||||
"Convert all type literals to mapped type": {
|
||||
"category": "Message",
|
||||
"code": 95021
|
||||
},
|
||||
"Add all missing members": {
|
||||
"category": "Message",
|
||||
"code": 95022
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixId = "convertLiteralTypeToMappedType";
|
||||
const errorCodes = [Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_1_in_0.code];
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions: context => {
|
||||
const { sourceFile, span } = context;
|
||||
const info = getInfo(sourceFile, span.start);
|
||||
if (!info) {
|
||||
return undefined;
|
||||
}
|
||||
const { name, constraint } = info;
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info));
|
||||
return [createCodeFixAction(fixId, changes, [Diagnostics.Convert_0_to_1_in_0, constraint, name], fixId, Diagnostics.Convert_all_type_literals_to_mapped_type)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const info = getInfo(diag.file, diag.start);
|
||||
if (info) {
|
||||
doChange(changes, diag.file, info);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
interface Info {
|
||||
container: TypeLiteralNode,
|
||||
typeNode: TypeNode | undefined;
|
||||
constraint: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
function getInfo(sourceFile: SourceFile, pos: number): Info | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
if (isIdentifier(token)) {
|
||||
const propertySignature = cast(token.parent.parent, isPropertySignature);
|
||||
const propertyName = token.getText(sourceFile);
|
||||
return {
|
||||
container: cast(propertySignature.parent, isTypeLiteralNode),
|
||||
typeNode: propertySignature.type,
|
||||
constraint: propertyName,
|
||||
name: propertyName === "K" ? "P" : "K",
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { container, typeNode, constraint, name }: Info): void {
|
||||
changes.replaceNode(sourceFile, container, factory.createMappedTypeNode(/*readonlyToken*/ undefined,
|
||||
factory.createTypeParameterDeclaration(name, factory.createTypeReferenceNode(constraint)), /*questionToken*/ undefined, typeNode));
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,7 @@
|
||||
"codefixes/correctQualifiedNameToIndexedAccessType.ts",
|
||||
"codefixes/convertToTypeOnlyExport.ts",
|
||||
"codefixes/convertToTypeOnlyImport.ts",
|
||||
"codefixes/convertLiteralTypeToMappedType.ts",
|
||||
"codefixes/fixClassIncorrectlyImplementsInterface.ts",
|
||||
"codefixes/importFixes.ts",
|
||||
"codefixes/fixImplicitThis.ts",
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////type K = number | string;
|
||||
////type T = {
|
||||
//// [K]: number;
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Convert_0_to_1_in_0.message, "K", "P"],
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`type K = number | string;
|
||||
type T = {
|
||||
[P in K]: number;
|
||||
}`
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////type Keys = number | string;
|
||||
////type T = {
|
||||
//// [Keys]: number;
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: [ts.Diagnostics.Convert_0_to_1_in_0.message, "Keys", "K"],
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`type Keys = number | string;
|
||||
type T = {
|
||||
[K in Keys]: number;
|
||||
}`
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////type K1 = number | string;
|
||||
////type T1 = {
|
||||
//// [K1]: number;
|
||||
////}
|
||||
////type K2 = number | string;
|
||||
////type T2 = {
|
||||
//// [K2]: number;
|
||||
////}
|
||||
|
||||
verify.codeFixAll({
|
||||
fixAllDescription: ts.Diagnostics.Convert_all_type_literals_to_mapped_type.message,
|
||||
fixId: 'convertLiteralTypeToMappedType',
|
||||
newFileContent:
|
||||
`type K1 = number | string;
|
||||
type T1 = {
|
||||
[K in K1]: number;
|
||||
}
|
||||
type K2 = number | string;
|
||||
type T2 = {
|
||||
[K in K2]: number;
|
||||
}`
|
||||
});
|
||||
Reference in New Issue
Block a user