@@ -8206,12 +8206,15 @@ namespace ts {
8206
8206
8207
8207
function getLiteralTypeFromPropertyName(prop: Symbol, include: TypeFlags) {
8208
8208
if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) {
8209
- const nameType = getLateBoundSymbol(prop).nameType;
8210
- if (nameType) {
8211
- return nameType.flags & include ? nameType : neverType;
8212
- }
8213
- if (!isKnownSymbol(prop)) {
8214
- return getLiteralType(symbolName(prop));
8209
+ let type = getLateBoundSymbol(prop).nameType;
8210
+ if (!type && !isKnownSymbol(prop)) {
8211
+ const name = getNameOfDeclaration(prop.valueDeclaration);
8212
+ type = name && isNumericLiteral(name) ? getLiteralType(+name.text) :
8213
+ name && name.kind === SyntaxKind.ComputedPropertyName && isNumericLiteral(name.expression) ? getLiteralType(+name.expression.text) :
8214
+ getLiteralType(symbolName(prop));
8215
+ }
8216
+ if (type && type.flags & include) {
8217
+ return type;
8215
8218
}
8216
8219
}
8217
8220
return neverType;
@@ -15369,6 +15372,7 @@ namespace ts {
15369
15372
let patternWithComputedProperties = false;
15370
15373
let hasComputedStringProperty = false;
15371
15374
let hasComputedNumberProperty = false;
15375
+
15372
15376
if (isInJSFile && node.properties.length === 0) {
15373
15377
// an empty JS object literal that nonetheless has members is a JS namespace
15374
15378
const symbol = getSymbolOfNode(node);
@@ -15384,47 +15388,28 @@ namespace ts {
15384
15388
for (let i = 0; i < node.properties.length; i++) {
15385
15389
const memberDecl = node.properties[i];
15386
15390
let member = getSymbolOfNode(memberDecl);
15387
- let literalName: __String | undefined;
15391
+ const computedNameType = memberDecl.name && memberDecl.name.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically(memberDecl.name.expression) ?
15392
+ checkComputedPropertyName(memberDecl.name) : undefined;
15388
15393
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
15389
15394
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
15390
15395
isObjectLiteralMethod(memberDecl)) {
15391
- let jsdocType: Type;
15396
+ let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) :
15397
+ memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(memberDecl.name, checkMode) :
15398
+ checkObjectLiteralMethod(memberDecl, checkMode);
15392
15399
if (isInJSFile) {
15393
- jsdocType = getTypeForDeclarationFromJSDocComment(memberDecl);
15394
- }
15395
-
15396
- let type: Type;
15397
- if (memberDecl.kind === SyntaxKind.PropertyAssignment) {
15398
- if (memberDecl.name.kind === SyntaxKind.ComputedPropertyName) {
15399
- const t = checkComputedPropertyName(memberDecl.name);
15400
- if (t.flags & TypeFlags.Literal) {
15401
- literalName = escapeLeadingUnderscores("" + (t as LiteralType).value);
15402
- }
15400
+ const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl);
15401
+ if (jsDocType) {
15402
+ checkTypeAssignableTo(type, jsDocType, memberDecl);
15403
+ type = jsDocType;
15403
15404
}
15404
- type = checkPropertyAssignment(memberDecl, checkMode);
15405
15405
}
15406
- else if (memberDecl.kind === SyntaxKind.MethodDeclaration) {
15407
- type = checkObjectLiteralMethod(memberDecl, checkMode);
15408
- }
15409
- else {
15410
- Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment);
15411
- type = checkExpressionForMutableLocation(memberDecl.name, checkMode);
15412
- }
15413
-
15414
- if (jsdocType) {
15415
- checkTypeAssignableTo(type, jsdocType, memberDecl);
15416
- type = jsdocType;
15417
- }
15418
-
15419
15406
typeFlags |= type.flags;
15420
-
15421
- const nameType = hasLateBindableName(memberDecl) ? checkComputedPropertyName(memberDecl.name) : undefined;
15422
- const hasLateBoundName = nameType && isTypeUsableAsLateBoundName(nameType);
15423
- const prop = hasLateBoundName
15424
- ? createSymbol(SymbolFlags.Property | member.flags, getLateBoundNameFromType(nameType as LiteralType | UniqueESSymbolType), CheckFlags.Late)
15425
- : createSymbol(SymbolFlags.Property | member.flags, literalName || member.escapedName);
15426
-
15427
- if (hasLateBoundName) {
15407
+ const nameType = computedNameType && computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique ?
15408
+ <LiteralType | UniqueESSymbolType>computedNameType : undefined;
15409
+ const prop = nameType ?
15410
+ createSymbol(SymbolFlags.Property | member.flags, getLateBoundNameFromType(nameType), CheckFlags.Late) :
15411
+ createSymbol(SymbolFlags.Property | member.flags, member.escapedName);
15412
+ if (nameType) {
15428
15413
prop.nameType = nameType;
15429
15414
}
15430
15415
@@ -15437,9 +15422,6 @@ namespace ts {
15437
15422
if (isOptional) {
15438
15423
prop.flags |= SymbolFlags.Optional;
15439
15424
}
15440
- if (!literalName && hasDynamicName(memberDecl)) {
15441
- patternWithComputedProperties = true;
15442
- }
15443
15425
}
15444
15426
else if (contextualTypeHasPattern && !(getObjectFlags(contextualType) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
15445
15427
// If object literal is contextually typed by the implied type of a binding pattern, and if the
@@ -15495,12 +15477,17 @@ namespace ts {
15495
15477
checkNodeDeferred(memberDecl);
15496
15478
}
15497
15479
15498
- if (!literalName && hasNonBindableDynamicName(memberDecl)) {
15499
- if (isNumericName(memberDecl.name)) {
15500
- hasComputedNumberProperty = true;
15501
- }
15502
- else {
15503
- hasComputedStringProperty = true;
15480
+ if (computedNameType && !(computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique)) {
15481
+ if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) {
15482
+ if (isTypeAssignableTo(computedNameType, numberType)) {
15483
+ hasComputedNumberProperty = true;
15484
+ }
15485
+ else {
15486
+ hasComputedStringProperty = true;
15487
+ }
15488
+ if (inDestructuringPattern) {
15489
+ patternWithComputedProperties = true;
15490
+ }
15504
15491
}
15505
15492
}
15506
15493
else {
0 commit comments