@@ -8206,12 +8206,15 @@ namespace ts {
82068206
82078207 function getLiteralTypeFromPropertyName(prop: Symbol, include: TypeFlags) {
82088208 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;
82158218 }
82168219 }
82178220 return neverType;
@@ -15369,6 +15372,7 @@ namespace ts {
1536915372 let patternWithComputedProperties = false;
1537015373 let hasComputedStringProperty = false;
1537115374 let hasComputedNumberProperty = false;
15375+
1537215376 if (isInJSFile && node.properties.length === 0) {
1537315377 // an empty JS object literal that nonetheless has members is a JS namespace
1537415378 const symbol = getSymbolOfNode(node);
@@ -15384,47 +15388,28 @@ namespace ts {
1538415388 for (let i = 0; i < node.properties.length; i++) {
1538515389 const memberDecl = node.properties[i];
1538615390 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;
1538815393 if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
1538915394 memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
1539015395 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);
1539215399 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;
1540315404 }
15404- type = checkPropertyAssignment(memberDecl, checkMode);
1540515405 }
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-
1541915406 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) {
1542815413 prop.nameType = nameType;
1542915414 }
1543015415
@@ -15437,9 +15422,6 @@ namespace ts {
1543715422 if (isOptional) {
1543815423 prop.flags |= SymbolFlags.Optional;
1543915424 }
15440- if (!literalName && hasDynamicName(memberDecl)) {
15441- patternWithComputedProperties = true;
15442- }
1544315425 }
1544415426 else if (contextualTypeHasPattern && !(getObjectFlags(contextualType) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
1544515427 // If object literal is contextually typed by the implied type of a binding pattern, and if the
@@ -15495,12 +15477,17 @@ namespace ts {
1549515477 checkNodeDeferred(memberDecl);
1549615478 }
1549715479
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+ }
1550415491 }
1550515492 }
1550615493 else {
0 commit comments