1/* @internal */ 2namespace ts.codefix { 3 const fixId = "convertLiteralTypeToMappedType"; 4 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]; 5 6 registerCodeFix({ 7 errorCodes, 8 getCodeActions: function getCodeActionsToConvertLiteralTypeToMappedType(context) { 9 const { sourceFile, span } = context; 10 const info = getInfo(sourceFile, span.start); 11 if (!info) { 12 return undefined; 13 } 14 const { name, constraint } = info; 15 const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info)); 16 return [createCodeFixAction(fixId, changes, [Diagnostics.Convert_0_to_1_in_0, constraint, name], fixId, Diagnostics.Convert_all_type_literals_to_mapped_type)]; 17 }, 18 fixIds: [fixId], 19 getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { 20 const info = getInfo(diag.file, diag.start); 21 if (info) { 22 doChange(changes, diag.file, info); 23 } 24 }) 25 }); 26 27 interface Info { 28 container: TypeLiteralNode, 29 typeNode: TypeNode | undefined; 30 constraint: string; 31 name: string; 32 } 33 34 function getInfo(sourceFile: SourceFile, pos: number): Info | undefined { 35 const token = getTokenAtPosition(sourceFile, pos); 36 if (isIdentifier(token)) { 37 const propertySignature = cast(token.parent.parent, isPropertySignature); 38 const propertyName = token.getText(sourceFile); 39 return { 40 container: cast(propertySignature.parent, isTypeLiteralNode), 41 typeNode: propertySignature.type, 42 constraint: propertyName, 43 name: propertyName === "K" ? "P" : "K", 44 }; 45 } 46 return undefined; 47 } 48 49 function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { container, typeNode, constraint, name }: Info): void { 50 changes.replaceNode(sourceFile, container, factory.createMappedTypeNode( 51 /*readonlyToken*/ undefined, 52 factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, factory.createTypeReferenceNode(constraint)), 53 /*nameType*/ undefined, 54 /*questionToken*/ undefined, 55 typeNode, 56 /*members*/ undefined)); 57 } 58} 59