Give mapped type properties a synthetic declaration name (#18023)

* Escape symbol names which are not valid identifiers and wrap them in quotes

* Pass forward type, do work in getNameOfSymbol

* Minimal test

* Fix nit
This commit is contained in:
Wesley Wigham 2017-08-24 16:48:11 -07:00 committed by GitHub
parent 336df751ea
commit f824e7214d
6 changed files with 54 additions and 1 deletions

View file

@ -3114,6 +3114,12 @@ namespace ts {
return "(Anonymous function)";
}
}
if ((symbol as TransientSymbol).syntheticLiteralTypeOrigin) {
const stringValue = (symbol as TransientSymbol).syntheticLiteralTypeOrigin.value;
if (!isIdentifierText(stringValue, compilerOptions.target)) {
return `"${escapeString(stringValue, CharacterCodes.doubleQuote)}"`;
}
}
return unescapeLeadingUnderscores(symbol.escapedName);
}
@ -5724,7 +5730,14 @@ namespace ts {
}
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
function addMemberForKeyType(t: Type, propertySymbol?: Symbol) {
function addMemberForKeyType(t: Type, propertySymbolOrIndex?: Symbol | number) {
let propertySymbol: Symbol;
// forEachType delegates to forEach, which calls with a numeric second argument
// the type system currently doesn't catch this incompatibility, so we annotate
// the function ourselves to indicate the runtime behavior and deal with it here
if (typeof propertySymbolOrIndex === "object") {
propertySymbol = propertySymbolOrIndex;
}
// Create a mapper from T to the current iteration type constituent. Then, if the
// mapped type is itself an instantiated type, combine the iteration mapper with the
// instantiation mapper.
@ -5744,6 +5757,7 @@ namespace ts {
prop.syntheticOrigin = propertySymbol;
prop.declarations = propertySymbol.declarations;
}
prop.syntheticLiteralTypeOrigin = t as StringLiteralType;
members.set(propName, prop);
}
else if (t.flags & TypeFlags.String) {

View file

@ -2972,6 +2972,7 @@ namespace ts {
leftSpread?: Symbol; // Left source for synthetic spread property
rightSpread?: Symbol; // Right source for synthetic spread property
syntheticOrigin?: Symbol; // For a property on a mapped or spread type, points back to the original property
syntheticLiteralTypeOrigin?: StringLiteralType; // For a property on a mapped type, indicates the type whose text to use as the declaration name, instead of the symbol name
isDiscriminantProperty?: boolean; // True if discriminant synthetic property
resolvedExports?: SymbolTable; // Resolved exports of module
exportsChecked?: boolean; // True if exports of external module have been checked

View file

@ -0,0 +1,17 @@
//// [declarationQuotedMembers.ts]
export declare const mapped: { [K in 'a-b-c']: number }
export const example = mapped;
//// [declarationQuotedMembers.js]
"use strict";
exports.__esModule = true;
exports.example = exports.mapped;
//// [declarationQuotedMembers.d.ts]
export declare const mapped: {
[K in 'a-b-c']: number;
};
export declare const example: {
"a-b-c": number;
};

View file

@ -0,0 +1,9 @@
=== tests/cases/compiler/declarationQuotedMembers.ts ===
export declare const mapped: { [K in 'a-b-c']: number }
>mapped : Symbol(mapped, Decl(declarationQuotedMembers.ts, 0, 20))
>K : Symbol(K, Decl(declarationQuotedMembers.ts, 0, 32))
export const example = mapped;
>example : Symbol(example, Decl(declarationQuotedMembers.ts, 1, 12))
>mapped : Symbol(mapped, Decl(declarationQuotedMembers.ts, 0, 20))

View file

@ -0,0 +1,9 @@
=== tests/cases/compiler/declarationQuotedMembers.ts ===
export declare const mapped: { [K in 'a-b-c']: number }
>mapped : { a-b-c: number; }
>K : K
export const example = mapped;
>example : { a-b-c: number; }
>mapped : { a-b-c: number; }

View file

@ -0,0 +1,3 @@
// @declaration: true
export declare const mapped: { [K in 'a-b-c']: number }
export const example = mapped;