Preserve input key style when writing mapped type keys in declaration emit (#50781)

This commit is contained in:
Wesley Wigham 2022-11-18 12:54:12 -08:00 committed by GitHub
parent 89d9af2ab9
commit b4024a5506
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 4 deletions

View File

@ -7735,23 +7735,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function getPropertyNameNodeForSymbol(symbol: Symbol, context: NodeBuilderContext) {
const stringNamed = !!length(symbol.declarations) && every(symbol.declarations, isStringNamed);
const singleQuote = !!length(symbol.declarations) && every(symbol.declarations, isSingleQuotedStringNamed);
const fromNameType = getPropertyNameNodeForSymbolFromNameType(symbol, context, singleQuote);
const fromNameType = getPropertyNameNodeForSymbolFromNameType(symbol, context, singleQuote, stringNamed);
if (fromNameType) {
return fromNameType;
}
const rawName = unescapeLeadingUnderscores(symbol.escapedName);
const stringNamed = !!length(symbol.declarations) && every(symbol.declarations, isStringNamed);
return createPropertyNameNodeForIdentifierOrLiteral(rawName, getEmitScriptTarget(compilerOptions), singleQuote, stringNamed);
}
// See getNameForSymbolFromNameType for a stringy equivalent
function getPropertyNameNodeForSymbolFromNameType(symbol: Symbol, context: NodeBuilderContext, singleQuote?: boolean) {
function getPropertyNameNodeForSymbolFromNameType(symbol: Symbol, context: NodeBuilderContext, singleQuote?: boolean, stringNamed?: boolean) {
const nameType = getSymbolLinks(symbol).nameType;
if (nameType) {
if (nameType.flags & TypeFlags.StringOrNumberLiteral) {
const name = "" + (nameType as StringLiteralType | NumberLiteralType).value;
if (!isIdentifierText(name, getEmitScriptTarget(compilerOptions)) && !isNumericLiteralName(name)) {
if (!isIdentifierText(name, getEmitScriptTarget(compilerOptions)) && (stringNamed || !isNumericLiteralName(name))) {
return factory.createStringLiteral(name, !!singleQuote);
}
if (isNumericLiteralName(name) && startsWith(name, "-")) {

View File

@ -0,0 +1,14 @@
//// [declarationEmitMappedTypePropertyFromNumericStringKey.ts]
export const f = (<T>(arg: {[K in keyof T]: T[K] | string}) => arg)({'0': 0}); // Original prop uses string syntax
//// [declarationEmitMappedTypePropertyFromNumericStringKey.js]
"use strict";
exports.__esModule = true;
exports.f = void 0;
exports.f = (function (arg) { return arg; })({ '0': 0 }); // Original prop uses string syntax
//// [declarationEmitMappedTypePropertyFromNumericStringKey.d.ts]
export declare const f: {
'0': string | number;
};

View File

@ -0,0 +1,12 @@
=== tests/cases/compiler/declarationEmitMappedTypePropertyFromNumericStringKey.ts ===
export const f = (<T>(arg: {[K in keyof T]: T[K] | string}) => arg)({'0': 0}); // Original prop uses string syntax
>f : Symbol(f, Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 12))
>T : Symbol(T, Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 19))
>arg : Symbol(arg, Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 22))
>K : Symbol(K, Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 29))
>T : Symbol(T, Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 19))
>T : Symbol(T, Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 19))
>K : Symbol(K, Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 29))
>arg : Symbol(arg, Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 22))
>'0' : Symbol('0', Decl(declarationEmitMappedTypePropertyFromNumericStringKey.ts, 0, 69))

View File

@ -0,0 +1,12 @@
=== tests/cases/compiler/declarationEmitMappedTypePropertyFromNumericStringKey.ts ===
export const f = (<T>(arg: {[K in keyof T]: T[K] | string}) => arg)({'0': 0}); // Original prop uses string syntax
>f : { '0': string | number; }
>(<T>(arg: {[K in keyof T]: T[K] | string}) => arg)({'0': 0}) : { '0': string | number; }
>(<T>(arg: {[K in keyof T]: T[K] | string}) => arg) : <T>(arg: { [K in keyof T]: string | T[K]; }) => { [K in keyof T]: string | T[K]; }
><T>(arg: {[K in keyof T]: T[K] | string}) => arg : <T>(arg: { [K in keyof T]: string | T[K]; }) => { [K in keyof T]: string | T[K]; }
>arg : { [K in keyof T]: string | T[K]; }
>arg : { [K in keyof T]: string | T[K]; }
>{'0': 0} : { '0': number; }
>'0' : number
>0 : 0

View File

@ -0,0 +1,2 @@
// @declaration: true
export const f = (<T>(arg: {[K in keyof T]: T[K] | string}) => arg)({'0': 0}); // Original prop uses string syntax