mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-23 07:07:09 -05:00
fix(54694): Class incorrectly implements interface generated with template string literal mapped type (#54715)
This commit is contained in:
@@ -6,27 +6,32 @@ import {
|
||||
Block,
|
||||
CallExpression,
|
||||
CharacterCodes,
|
||||
CheckFlags,
|
||||
ClassLikeDeclaration,
|
||||
CodeFixContextBase,
|
||||
combine,
|
||||
Debug,
|
||||
Declaration,
|
||||
Diagnostics,
|
||||
emptyArray,
|
||||
EntityName,
|
||||
Expression,
|
||||
factory,
|
||||
find,
|
||||
firstOrUndefined,
|
||||
flatMap,
|
||||
FunctionDeclaration,
|
||||
FunctionExpression,
|
||||
GetAccessorDeclaration,
|
||||
getAllAccessorDeclarations,
|
||||
getCheckFlags,
|
||||
getEffectiveModifierFlags,
|
||||
getEmitScriptTarget,
|
||||
getFirstIdentifier,
|
||||
getModuleSpecifierResolverHost,
|
||||
getNameForExportedSymbol,
|
||||
getNameOfDeclaration,
|
||||
getPropertyNameFromType,
|
||||
getQuotePreference,
|
||||
getSetAccessorValueParameter,
|
||||
getSynthesizedDeepClone,
|
||||
@@ -52,6 +57,7 @@ import {
|
||||
isSetAccessorDeclaration,
|
||||
isStringLiteral,
|
||||
isTypeNode,
|
||||
isTypeUsableAsPropertyName,
|
||||
isYieldExpression,
|
||||
LanguageServiceHost,
|
||||
length,
|
||||
@@ -91,6 +97,7 @@ import {
|
||||
textChanges,
|
||||
TextSpan,
|
||||
textSpanEnd,
|
||||
TransientSymbol,
|
||||
tryCast,
|
||||
TsConfigSourceFile,
|
||||
Type,
|
||||
@@ -98,6 +105,7 @@ import {
|
||||
TypeFlags,
|
||||
TypeNode,
|
||||
TypeParameterDeclaration,
|
||||
unescapeLeadingUnderscores,
|
||||
UnionType,
|
||||
UserPreferences,
|
||||
visitEachChild,
|
||||
@@ -174,7 +182,7 @@ export function addNewNodeForMemberSymbol(
|
||||
isAmbient = false,
|
||||
): void {
|
||||
const declarations = symbol.getDeclarations();
|
||||
const declaration = declarations?.[0];
|
||||
const declaration = firstOrUndefined(declarations);
|
||||
const checker = context.program.getTypeChecker();
|
||||
const scriptTarget = getEmitScriptTarget(context.program.getCompilerOptions());
|
||||
|
||||
@@ -193,7 +201,7 @@ export function addNewNodeForMemberSymbol(
|
||||
* In such cases, we assume the declaration to be a `PropertySignature`.
|
||||
*/
|
||||
const kind = declaration?.kind ?? SyntaxKind.PropertySignature;
|
||||
const declarationName = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName;
|
||||
const declarationName = createDeclarationName(symbol, declaration);
|
||||
const effectiveModifierFlags = declaration ? getEffectiveModifierFlags(declaration) : ModifierFlags.None;
|
||||
let modifierFlags = effectiveModifierFlags & ModifierFlags.Static;
|
||||
modifierFlags |=
|
||||
@@ -310,7 +318,6 @@ export function addNewNodeForMemberSymbol(
|
||||
if (method) addClassElement(method);
|
||||
}
|
||||
|
||||
|
||||
function createModifiers(): NodeArray<Modifier> | undefined {
|
||||
let modifiers: Modifier[] | undefined;
|
||||
|
||||
@@ -344,6 +351,16 @@ export function addNewNodeForMemberSymbol(
|
||||
function createTypeNode(typeNode: TypeNode | undefined) {
|
||||
return getSynthesizedDeepClone(typeNode, /*includeTrivia*/ false);
|
||||
}
|
||||
|
||||
function createDeclarationName(symbol: Symbol, declaration: Declaration | undefined): PropertyName {
|
||||
if (getCheckFlags(symbol) & CheckFlags.Mapped) {
|
||||
const nameType = (symbol as TransientSymbol).links.nameType;
|
||||
if (nameType && isTypeUsableAsPropertyName(nameType)) {
|
||||
return factory.createIdentifier(unescapeLeadingUnderscores(getPropertyNameFromType(nameType)));
|
||||
}
|
||||
}
|
||||
return getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName;
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
Reference in New Issue
Block a user