@@ -30099,18 +30099,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3009930099 isTypeAssignableToKind(checkComputedPropertyName(firstDecl.name), TypeFlags.ESSymbol));
3010030100 }
3010130101
30102- function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], keyType: Type): IndexInfo {
30102+ function getObjectLiteralIndexInfo(offset: number, properties: Symbol[], keyType: Type, isReadonly: boolean ): IndexInfo {
3010330103 const propTypes: Type[] = [];
3010430104 for (let i = offset; i < properties.length; i++) {
3010530105 const prop = properties[i];
30106- if (keyType === stringType && !isSymbolWithSymbolName(prop) ||
30107- keyType === numberType && isSymbolWithNumericName(prop) ||
30108- keyType === esSymbolType && isSymbolWithSymbolName(prop)) {
30106+ if (keyType === numberType && isSymbolWithNumericName(prop) || keyType === esSymbolType && isSymbolWithSymbolName(prop)) {
3010930107 propTypes.push(getTypeOfSymbol(properties[i]));
3011030108 }
30109+ else if (!isSymbolWithSymbolName(prop)) {
30110+ if (keyType === stringType) {
30111+ propTypes.push(getTypeOfSymbol(properties[i]));
30112+ }
30113+ else {
30114+ const source = tryCast(prop, isTransientSymbol)?.links.computedNameType || getStringLiteralType(unescapeLeadingUnderscores(prop.escapedName));
30115+ if (isTypeAssignableTo(source, keyType)) {
30116+ propTypes.push(getTypeOfSymbol(properties[i]));
30117+ }
30118+ }
30119+ }
3011130120 }
3011230121 const unionType = propTypes.length ? getUnionType(propTypes, UnionReduction.Subtype) : undefinedType;
30113- return createIndexInfo(keyType, unionType, isConstContext(node) );
30122+ return createIndexInfo(keyType, unionType, isReadonly );
3011430123 }
3011530124
3011630125 function getImmediateAliasedSymbol(symbol: Symbol): Symbol | undefined {
@@ -30133,6 +30142,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3013330142 const allPropertiesTable = strictNullChecks ? createSymbolTable() : undefined;
3013430143 let propertiesTable = createSymbolTable();
3013530144 let propertiesArray: Symbol[] = [];
30145+ let computedNameTypes: Type[] = [];
3013630146 let spread: Type = emptyObjectType;
3013730147
3013830148 pushCachedContextualType(node);
@@ -30191,7 +30201,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3019130201 if (nameType) {
3019230202 prop.links.nameType = nameType;
3019330203 }
30194-
30204+ else if (computedNameType) {
30205+ prop.links.computedNameType = computedNameType;
30206+ }
3019530207 if (inDestructuringPattern) {
3019630208 // If object literal is an assignment pattern and if the assignment pattern specifies a default value
3019730209 // for the property, make the property optional.
@@ -30243,6 +30255,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3024330255 spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
3024430256 propertiesArray = [];
3024530257 propertiesTable = createSymbolTable();
30258+ computedNameTypes = [];
3024630259 hasComputedStringProperty = false;
3024730260 hasComputedNumberProperty = false;
3024830261 hasComputedSymbolProperty = false;
@@ -30275,8 +30288,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3027530288 checkNodeDeferred(memberDecl);
3027630289 }
3027730290
30278- if (computedNameType && !(computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique)) {
30279- if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) {
30291+ if (computedNameType && !isTypeUsableAsPropertyName(computedNameType)) {
30292+ if (isPatternLiteralType(computedNameType)) {
30293+ computedNameTypes.push(computedNameType);
30294+ }
30295+ else if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) {
3028030296 if (isTypeAssignableTo(computedNameType, numberType)) {
3028130297 hasComputedNumberProperty = true;
3028230298 }
@@ -30339,6 +30355,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3033930355 spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
3034030356 propertiesArray = [];
3034130357 propertiesTable = createSymbolTable();
30358+ computedNameTypes = [];
3034230359 hasComputedStringProperty = false;
3034330360 hasComputedNumberProperty = false;
3034430361 }
@@ -30349,10 +30366,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3034930366 return createObjectLiteralType();
3035030367
3035130368 function createObjectLiteralType() {
30352- const indexInfos = [];
30353- if (hasComputedStringProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, stringType));
30354- if (hasComputedNumberProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, numberType));
30355- if (hasComputedSymbolProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, esSymbolType));
30369+ let indexInfos: IndexInfo[] = [];
30370+ for (const computedNameType of computedNameTypes) {
30371+ const indexInfo = getObjectLiteralIndexInfo(offset, propertiesArray, computedNameType, /*isReadonly*/ inConstContext);
30372+ indexInfos = appendIndexInfo(indexInfos, indexInfo, /*union*/ true);
30373+ }
30374+ if (hasComputedStringProperty) indexInfos.push(getObjectLiteralIndexInfo(offset, propertiesArray, stringType, /*isReadonly*/ inConstContext));
30375+ if (hasComputedNumberProperty) indexInfos.push(getObjectLiteralIndexInfo(offset, propertiesArray, numberType, /*isReadonly*/ inConstContext));
30376+ if (hasComputedSymbolProperty) indexInfos.push(getObjectLiteralIndexInfo(offset, propertiesArray, esSymbolType, /*isReadonly*/ inConstContext));
3035630377 const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, indexInfos);
3035730378 result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral;
3035830379 if (isJSObjectLiteral) {
0 commit comments