diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 33e86be3a9ba9..4601a2b8d981c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31603,20 +31603,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { isTypeAssignableToKind(checkComputedPropertyName(firstDecl.name), TypeFlags.ESSymbol)); } - function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], keyType: Type): IndexInfo { + function getObjectLiteralIndexInfo(offset: number, properties: Symbol[], keyType: Type, isReadonly: boolean): IndexInfo { const propTypes: Type[] = []; for (let i = offset; i < properties.length; i++) { const prop = properties[i]; - if ( - keyType === stringType && !isSymbolWithSymbolName(prop) || - keyType === numberType && isSymbolWithNumericName(prop) || - keyType === esSymbolType && isSymbolWithSymbolName(prop) - ) { + if (keyType === numberType && isSymbolWithNumericName(prop) || keyType === esSymbolType && isSymbolWithSymbolName(prop)) { propTypes.push(getTypeOfSymbol(properties[i])); } + else if (!isSymbolWithSymbolName(prop)) { + if (keyType === stringType) { + propTypes.push(getTypeOfSymbol(properties[i])); + } + else { + const source = getSymbolLinks(prop).computedNameType || getStringLiteralType(unescapeLeadingUnderscores(prop.escapedName)); + if (isTypeAssignableTo(source, keyType)) { + propTypes.push(getTypeOfSymbol(properties[i])); + } + } + } } const unionType = propTypes.length ? getUnionType(propTypes, UnionReduction.Subtype) : undefinedType; - return createIndexInfo(keyType, unionType, isConstContext(node)); + return createIndexInfo(keyType, unionType, isReadonly); } function getImmediateAliasedSymbol(symbol: Symbol): Symbol | undefined { @@ -31639,6 +31646,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const allPropertiesTable = strictNullChecks ? createSymbolTable() : undefined; let propertiesTable = createSymbolTable(); let propertiesArray: Symbol[] = []; + let indexKeyTypes = new Set<Type>(); let spread: Type = emptyObjectType; pushCachedContextualType(node); @@ -31652,9 +31660,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const isJSObjectLiteral = !contextualType && isInJavascript && !enumTag; let objectFlags: ObjectFlags = ObjectFlags.FreshLiteral; let patternWithComputedProperties = false; - let hasComputedStringProperty = false; - let hasComputedNumberProperty = false; - let hasComputedSymbolProperty = false; // Spreads may cause an early bail; ensure computed names are always checked (this is cached) // As otherwise they may not be checked until exports for the type at this position are retrieved, @@ -31699,7 +31704,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (nameType) { prop.links.nameType = nameType; } - + else if (computedNameType) { + prop.links.computedNameType = computedNameType; + } if (inDestructuringPattern) { // If object literal is an assignment pattern and if the assignment pattern specifies a default value // for the property, make the property optional. @@ -31750,9 +31757,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext); propertiesArray = []; propertiesTable = createSymbolTable(); - hasComputedStringProperty = false; - hasComputedNumberProperty = false; - hasComputedSymbolProperty = false; + indexKeyTypes = new Set(); } const type = getReducedType(checkExpression(memberDecl.expression, checkMode & CheckMode.Inferential)); if (isValidSpreadType(type)) { @@ -31782,16 +31787,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { checkNodeDeferred(memberDecl); } - if (computedNameType && !(computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique)) { - if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) { + if (computedNameType && !isTypeUsableAsPropertyName(computedNameType)) { + if (isPatternLiteralType(computedNameType)) { + indexKeyTypes.add(computedNameType); + } + else if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) { if (isTypeAssignableTo(computedNameType, numberType)) { - hasComputedNumberProperty = true; + indexKeyTypes.add(numberType); } else if (isTypeAssignableTo(computedNameType, esSymbolType)) { - hasComputedSymbolProperty = true; + indexKeyTypes.add(esSymbolType); } else { - hasComputedStringProperty = true; + indexKeyTypes.add(stringType); } if (inDestructuringPattern) { patternWithComputedProperties = true; @@ -31843,8 +31851,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext); propertiesArray = []; propertiesTable = createSymbolTable(); - hasComputedStringProperty = false; - hasComputedNumberProperty = false; + indexKeyTypes = new Set(); } // remap the raw emptyObjectType fed in at the top into a fresh empty object literal type, unique to this use site return mapType(spread, t => t === emptyObjectType ? createObjectLiteralType() : t); @@ -31853,10 +31860,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createObjectLiteralType(); function createObjectLiteralType() { - const indexInfos = []; - if (hasComputedStringProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, stringType)); - if (hasComputedNumberProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, numberType)); - if (hasComputedSymbolProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, esSymbolType)); + const indexInfos: IndexInfo[] = []; + for (const keyType of indexKeyTypes) { + indexInfos.push(getObjectLiteralIndexInfo(offset, propertiesArray, keyType, /*isReadonly*/ inConstContext)); + } const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, indexInfos); result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; if (isJSObjectLiteral) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ad08381d2eff1..f3dbae1095bff 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5915,6 +5915,7 @@ export interface SymbolLinks { type?: Type; // Type of value symbol writeType?: Type; // Type of value symbol in write contexts nameType?: Type; // Type associated with a late-bound symbol + computedNameType?: Type; // Type of the computed property name not usable as property name uniqueESSymbolType?: Type; // UniqueESSymbol type for a symbol declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic) diff --git a/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.errors.txt b/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.errors.txt new file mode 100644 index 0000000000000..5d8cec76fe3ba --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.errors.txt @@ -0,0 +1,122 @@ +computedPropertyNamesTemplateLiteralTypes.ts(94,7): error TS2322: Type '{ [x: string]: string | number[]; name: string; }' is not assignable to type 'IDocument_46309'. + 'string' and '`added_${string}`' index signatures are incompatible. + Type 'string | number[]' is not assignable to type 'number[] | undefined'. + Type 'string' is not assignable to type 'number[]'. + + +==== computedPropertyNamesTemplateLiteralTypes.ts (1 errors) ==== + declare const str1: string; + declare const pattern1: `foo${string}`; + declare const pattern2: `foobar${string}`; + declare const samepattern1: `foo${string}`; + + const obj1 = { + [pattern1]: true, + }; + + const obj2 = { + [pattern1]: true, + [str1]: 100, + }; + + const obj3 = { + [str1]: 100, + [pattern1]: true, + }; + + const obj4 = { + [pattern1]: true, + [pattern2]: "hello", + }; + + const obj5 = { + [pattern2]: "hello", + [pattern1]: true, + }; + + const obj6 = { + [pattern1]: true, + [pattern2]: "hello", + other: 100, + }; + + const obj7 = { + [pattern1]: true, + [pattern2]: "hello", + fooooooooo: 100, + }; + + const obj8 = { + [pattern1]: true, + [pattern2]: "hello", + foobarrrrr: 100, + }; + + const obj9 = { + [pattern1]: true, + [samepattern1]: "hello", + }; + + const obj10 = { + [pattern1]: true, + } as const; + + const obj11 = { + [pattern1]: 100, + ...obj9, + }; + + const obj12 = { + ...obj9, + [pattern1]: 100, + }; + + const obj13 = { + [pattern1]: 100, + ...{ + [pattern2]: "hello", + }, + }; + + const obj14 = { + [pattern1]: 100, + ...{ + [pattern1]: true, + [pattern2]: "hello", + foobarrrrr: [1, 2, 3], + }, + }; + + // repro from https://github.com/microsoft/TypeScript/issues/46309 + + interface IDocument_46309 { + name: string; + [added_: `added_${string}`]: number[] | undefined; + } + + const tech1_46309 = { + uuid: "70b26275-5096-4e4b-9d50-3c965c9e5073", + }; + + const doc_46309: IDocument_46309 = { + ~~~~~~~~~ +!!! error TS2322: Type '{ [x: string]: string | number[]; name: string; }' is not assignable to type 'IDocument_46309'. +!!! error TS2322: 'string' and '`added_${string}`' index signatures are incompatible. +!!! error TS2322: Type 'string | number[]' is not assignable to type 'number[] | undefined'. +!!! error TS2322: Type 'string' is not assignable to type 'number[]'. + name: "", + [`added_${tech1_46309.uuid}`]: [19700101], + }; + + const doc2_46309: IDocument_46309 = { + name: "", + [`added_${tech1_46309.uuid}` as const]: [19700101], + }; + + function genericFn1<T extends string>(input: T) { + const genericPattern = `get${input}` as const; + return { + [genericPattern]: 1, + }; + } + \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.js b/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.js new file mode 100644 index 0000000000000..0b3d9c7a8906d --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.js @@ -0,0 +1,196 @@ +//// [tests/cases/conformance/es6/computedProperties/computedPropertyNamesTemplateLiteralTypes.ts] //// + +//// [computedPropertyNamesTemplateLiteralTypes.ts] +declare const str1: string; +declare const pattern1: `foo${string}`; +declare const pattern2: `foobar${string}`; +declare const samepattern1: `foo${string}`; + +const obj1 = { + [pattern1]: true, +}; + +const obj2 = { + [pattern1]: true, + [str1]: 100, +}; + +const obj3 = { + [str1]: 100, + [pattern1]: true, +}; + +const obj4 = { + [pattern1]: true, + [pattern2]: "hello", +}; + +const obj5 = { + [pattern2]: "hello", + [pattern1]: true, +}; + +const obj6 = { + [pattern1]: true, + [pattern2]: "hello", + other: 100, +}; + +const obj7 = { + [pattern1]: true, + [pattern2]: "hello", + fooooooooo: 100, +}; + +const obj8 = { + [pattern1]: true, + [pattern2]: "hello", + foobarrrrr: 100, +}; + +const obj9 = { + [pattern1]: true, + [samepattern1]: "hello", +}; + +const obj10 = { + [pattern1]: true, +} as const; + +const obj11 = { + [pattern1]: 100, + ...obj9, +}; + +const obj12 = { + ...obj9, + [pattern1]: 100, +}; + +const obj13 = { + [pattern1]: 100, + ...{ + [pattern2]: "hello", + }, +}; + +const obj14 = { + [pattern1]: 100, + ...{ + [pattern1]: true, + [pattern2]: "hello", + foobarrrrr: [1, 2, 3], + }, +}; + +// repro from https://github.com/microsoft/TypeScript/issues/46309 + +interface IDocument_46309 { + name: string; + [added_: `added_${string}`]: number[] | undefined; +} + +const tech1_46309 = { + uuid: "70b26275-5096-4e4b-9d50-3c965c9e5073", +}; + +const doc_46309: IDocument_46309 = { + name: "", + [`added_${tech1_46309.uuid}`]: [19700101], +}; + +const doc2_46309: IDocument_46309 = { + name: "", + [`added_${tech1_46309.uuid}` as const]: [19700101], +}; + +function genericFn1<T extends string>(input: T) { + const genericPattern = `get${input}` as const; + return { + [genericPattern]: 1, + }; +} + + +//// [computedPropertyNamesTemplateLiteralTypes.js] +"use strict"; +const obj1 = { + [pattern1]: true, +}; +const obj2 = { + [pattern1]: true, + [str1]: 100, +}; +const obj3 = { + [str1]: 100, + [pattern1]: true, +}; +const obj4 = { + [pattern1]: true, + [pattern2]: "hello", +}; +const obj5 = { + [pattern2]: "hello", + [pattern1]: true, +}; +const obj6 = { + [pattern1]: true, + [pattern2]: "hello", + other: 100, +}; +const obj7 = { + [pattern1]: true, + [pattern2]: "hello", + fooooooooo: 100, +}; +const obj8 = { + [pattern1]: true, + [pattern2]: "hello", + foobarrrrr: 100, +}; +const obj9 = { + [pattern1]: true, + [samepattern1]: "hello", +}; +const obj10 = { + [pattern1]: true, +}; +const obj11 = { + [pattern1]: 100, + ...obj9, +}; +const obj12 = { + ...obj9, + [pattern1]: 100, +}; +const obj13 = { + [pattern1]: 100, + ...{ + [pattern2]: "hello", + }, +}; +const obj14 = { + [pattern1]: 100, + ...{ + [pattern1]: true, + [pattern2]: "hello", + foobarrrrr: [1, 2, 3], + }, +}; +const tech1_46309 = { + uuid: "70b26275-5096-4e4b-9d50-3c965c9e5073", +}; +const doc_46309 = { + name: "", + [`added_${tech1_46309.uuid}`]: [19700101], +}; +const doc2_46309 = { + name: "", + [`added_${tech1_46309.uuid}`]: [19700101], +}; +function genericFn1(input) { + const genericPattern = `get${input}`; + return { + [genericPattern]: 1, + }; +} diff --git a/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.symbols b/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.symbols new file mode 100644 index 0000000000000..eb477f6a06739 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.symbols @@ -0,0 +1,278 @@ +//// [tests/cases/conformance/es6/computedProperties/computedPropertyNamesTemplateLiteralTypes.ts] //// + +=== computedPropertyNamesTemplateLiteralTypes.ts === +declare const str1: string; +>str1 : Symbol(str1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 0, 13)) + +declare const pattern1: `foo${string}`; +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + +declare const pattern2: `foobar${string}`; +>pattern2 : Symbol(pattern2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 2, 13)) + +declare const samepattern1: `foo${string}`; +>samepattern1 : Symbol(samepattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 3, 13)) + +const obj1 = { +>obj1 : Symbol(obj1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 5, 5)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 5, 14)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + +}; + +const obj2 = { +>obj2 : Symbol(obj2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 9, 5)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 9, 14)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + [str1]: 100, +>[str1] : Symbol([str1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 10, 19)) +>str1 : Symbol(str1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 0, 13)) + +}; + +const obj3 = { +>obj3 : Symbol(obj3, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 14, 5)) + + [str1]: 100, +>[str1] : Symbol([str1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 14, 14)) +>str1 : Symbol(str1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 0, 13)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 15, 14)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + +}; + +const obj4 = { +>obj4 : Symbol(obj4, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 19, 5)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 19, 14)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + [pattern2]: "hello", +>[pattern2] : Symbol([pattern2], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 20, 19)) +>pattern2 : Symbol(pattern2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 2, 13)) + +}; + +const obj5 = { +>obj5 : Symbol(obj5, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 24, 5)) + + [pattern2]: "hello", +>[pattern2] : Symbol([pattern2], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 24, 14)) +>pattern2 : Symbol(pattern2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 2, 13)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 25, 22)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + +}; + +const obj6 = { +>obj6 : Symbol(obj6, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 29, 5)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 29, 14)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + [pattern2]: "hello", +>[pattern2] : Symbol([pattern2], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 30, 19)) +>pattern2 : Symbol(pattern2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 2, 13)) + + other: 100, +>other : Symbol(other, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 31, 22)) + +}; + +const obj7 = { +>obj7 : Symbol(obj7, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 35, 5)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 35, 14)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + [pattern2]: "hello", +>[pattern2] : Symbol([pattern2], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 36, 19)) +>pattern2 : Symbol(pattern2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 2, 13)) + + fooooooooo: 100, +>fooooooooo : Symbol(fooooooooo, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 37, 22)) + +}; + +const obj8 = { +>obj8 : Symbol(obj8, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 41, 5)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 41, 14)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + [pattern2]: "hello", +>[pattern2] : Symbol([pattern2], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 42, 19)) +>pattern2 : Symbol(pattern2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 2, 13)) + + foobarrrrr: 100, +>foobarrrrr : Symbol(foobarrrrr, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 43, 22)) + +}; + +const obj9 = { +>obj9 : Symbol(obj9, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 47, 5)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 47, 14)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + [samepattern1]: "hello", +>[samepattern1] : Symbol([samepattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 48, 19)) +>samepattern1 : Symbol(samepattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 3, 13)) + +}; + +const obj10 = { +>obj10 : Symbol(obj10, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 52, 5)) + + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 52, 15)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + +} as const; +>const : Symbol(const) + +const obj11 = { +>obj11 : Symbol(obj11, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 56, 5)) + + [pattern1]: 100, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 56, 15)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + ...obj9, +>obj9 : Symbol(obj9, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 47, 5)) + +}; + +const obj12 = { +>obj12 : Symbol(obj12, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 61, 5)) + + ...obj9, +>obj9 : Symbol(obj9, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 47, 5)) + + [pattern1]: 100, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 62, 10)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + +}; + +const obj13 = { +>obj13 : Symbol(obj13, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 66, 5)) + + [pattern1]: 100, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 66, 15)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + ...{ + [pattern2]: "hello", +>[pattern2] : Symbol([pattern2], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 68, 6)) +>pattern2 : Symbol(pattern2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 2, 13)) + + }, +}; + +const obj14 = { +>obj14 : Symbol(obj14, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 73, 5)) + + [pattern1]: 100, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 73, 15)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + ...{ + [pattern1]: true, +>[pattern1] : Symbol([pattern1], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 75, 6)) +>pattern1 : Symbol(pattern1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 1, 13)) + + [pattern2]: "hello", +>[pattern2] : Symbol([pattern2], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 76, 21)) +>pattern2 : Symbol(pattern2, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 2, 13)) + + foobarrrrr: [1, 2, 3], +>foobarrrrr : Symbol(foobarrrrr, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 77, 24)) + + }, +}; + +// repro from https://github.com/microsoft/TypeScript/issues/46309 + +interface IDocument_46309 { +>IDocument_46309 : Symbol(IDocument_46309, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 80, 2)) + + name: string; +>name : Symbol(IDocument_46309.name, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 84, 27)) + + [added_: `added_${string}`]: number[] | undefined; +>added_ : Symbol(added_, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 86, 3)) +} + +const tech1_46309 = { +>tech1_46309 : Symbol(tech1_46309, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 89, 5)) + + uuid: "70b26275-5096-4e4b-9d50-3c965c9e5073", +>uuid : Symbol(uuid, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 89, 21)) + +}; + +const doc_46309: IDocument_46309 = { +>doc_46309 : Symbol(doc_46309, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 93, 5)) +>IDocument_46309 : Symbol(IDocument_46309, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 80, 2)) + + name: "", +>name : Symbol(name, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 93, 36)) + + [`added_${tech1_46309.uuid}`]: [19700101], +>[`added_${tech1_46309.uuid}`] : Symbol([`added_${tech1_46309.uuid}`], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 94, 11)) +>tech1_46309.uuid : Symbol(uuid, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 89, 21)) +>tech1_46309 : Symbol(tech1_46309, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 89, 5)) +>uuid : Symbol(uuid, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 89, 21)) + +}; + +const doc2_46309: IDocument_46309 = { +>doc2_46309 : Symbol(doc2_46309, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 98, 5)) +>IDocument_46309 : Symbol(IDocument_46309, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 80, 2)) + + name: "", +>name : Symbol(name, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 98, 37)) + + [`added_${tech1_46309.uuid}` as const]: [19700101], +>[`added_${tech1_46309.uuid}` as const] : Symbol([`added_${tech1_46309.uuid}` as const], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 99, 11)) +>tech1_46309.uuid : Symbol(uuid, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 89, 21)) +>tech1_46309 : Symbol(tech1_46309, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 89, 5)) +>uuid : Symbol(uuid, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 89, 21)) +>const : Symbol(const) + +}; + +function genericFn1<T extends string>(input: T) { +>genericFn1 : Symbol(genericFn1, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 101, 2)) +>T : Symbol(T, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 103, 20)) +>input : Symbol(input, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 103, 38)) +>T : Symbol(T, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 103, 20)) + + const genericPattern = `get${input}` as const; +>genericPattern : Symbol(genericPattern, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 104, 7)) +>input : Symbol(input, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 103, 38)) +>const : Symbol(const) + + return { + [genericPattern]: 1, +>[genericPattern] : Symbol([genericPattern], Decl(computedPropertyNamesTemplateLiteralTypes.ts, 105, 10)) +>genericPattern : Symbol(genericPattern, Decl(computedPropertyNamesTemplateLiteralTypes.ts, 104, 7)) + + }; +} + diff --git a/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.types b/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.types new file mode 100644 index 0000000000000..60e1eb5af82c6 --- /dev/null +++ b/tests/baselines/reference/computedPropertyNamesTemplateLiteralTypes.types @@ -0,0 +1,500 @@ +//// [tests/cases/conformance/es6/computedProperties/computedPropertyNamesTemplateLiteralTypes.ts] //// + +=== computedPropertyNamesTemplateLiteralTypes.ts === +declare const str1: string; +>str1 : string +> : ^^^^^^ + +declare const pattern1: `foo${string}`; +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ + +declare const pattern2: `foobar${string}`; +>pattern2 : `foobar${string}` +> : ^^^^^^^^^^^^^^^^^ + +declare const samepattern1: `foo${string}`; +>samepattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ + +const obj1 = { +>obj1 : { [x: `foo${string}`]: boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true,} : { [x: `foo${string}`]: boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + +}; + +const obj2 = { +>obj2 : { [x: `foo${string}`]: boolean; [x: string]: number | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true, [str1]: 100,} : { [x: `foo${string}`]: boolean; [x: string]: number | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + + [str1]: 100, +>[str1] : number +> : ^^^^^^ +>str1 : string +> : ^^^^^^ +>100 : 100 +> : ^^^ + +}; + +const obj3 = { +>obj3 : { [x: string]: number | boolean; [x: `foo${string}`]: boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [str1]: 100, [pattern1]: true,} : { [x: string]: number | boolean; [x: `foo${string}`]: boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [str1]: 100, +>[str1] : number +> : ^^^^^^ +>str1 : string +> : ^^^^^^ +>100 : 100 +> : ^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + +}; + +const obj4 = { +>obj4 : { [x: `foo${string}`]: string | boolean; [x: `foobar${string}`]: string; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true, [pattern2]: "hello",} : { [x: `foo${string}`]: string | boolean; [x: `foobar${string}`]: string; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + + [pattern2]: "hello", +>[pattern2] : string +> : ^^^^^^ +>pattern2 : `foobar${string}` +> : ^^^^^^^^^^^^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + +}; + +const obj5 = { +>obj5 : { [x: `foobar${string}`]: string; [x: `foo${string}`]: string | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern2]: "hello", [pattern1]: true,} : { [x: `foobar${string}`]: string; [x: `foo${string}`]: string | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern2]: "hello", +>[pattern2] : string +> : ^^^^^^ +>pattern2 : `foobar${string}` +> : ^^^^^^^^^^^^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + +}; + +const obj6 = { +>obj6 : { [x: `foo${string}`]: string | boolean; [x: `foobar${string}`]: string; other: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true, [pattern2]: "hello", other: 100,} : { [x: `foo${string}`]: string | boolean; [x: `foobar${string}`]: string; other: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + + [pattern2]: "hello", +>[pattern2] : string +> : ^^^^^^ +>pattern2 : `foobar${string}` +> : ^^^^^^^^^^^^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + + other: 100, +>other : number +> : ^^^^^^ +>100 : 100 +> : ^^^ + +}; + +const obj7 = { +>obj7 : { [x: `foo${string}`]: string | number | boolean; [x: `foobar${string}`]: string; fooooooooo: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true, [pattern2]: "hello", fooooooooo: 100,} : { [x: `foo${string}`]: string | number | boolean; [x: `foobar${string}`]: string; fooooooooo: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + + [pattern2]: "hello", +>[pattern2] : string +> : ^^^^^^ +>pattern2 : `foobar${string}` +> : ^^^^^^^^^^^^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + + fooooooooo: 100, +>fooooooooo : number +> : ^^^^^^ +>100 : 100 +> : ^^^ + +}; + +const obj8 = { +>obj8 : { [x: `foo${string}`]: string | number | boolean; [x: `foobar${string}`]: string | number; foobarrrrr: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true, [pattern2]: "hello", foobarrrrr: 100,} : { [x: `foo${string}`]: string | number | boolean; [x: `foobar${string}`]: string | number; foobarrrrr: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + + [pattern2]: "hello", +>[pattern2] : string +> : ^^^^^^ +>pattern2 : `foobar${string}` +> : ^^^^^^^^^^^^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + + foobarrrrr: 100, +>foobarrrrr : number +> : ^^^^^^ +>100 : 100 +> : ^^^ + +}; + +const obj9 = { +>obj9 : { [x: `foo${string}`]: string | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true, [samepattern1]: "hello",} : { [x: `foo${string}`]: string | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + + [samepattern1]: "hello", +>[samepattern1] : string +> : ^^^^^^ +>samepattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + +}; + +const obj10 = { +>obj10 : { readonly [x: `foo${string}`]: true; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true,} as const : { readonly [x: `foo${string}`]: true; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: true,} : { readonly [x: `foo${string}`]: true; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : true +> : ^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + +} as const; + +const obj11 = { +>obj11 : { [x: `foo${string}`]: string | number | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: 100, ...obj9,} : { [x: `foo${string}`]: string | number | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: 100, +>[pattern1] : number +> : ^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>100 : 100 +> : ^^^ + + ...obj9, +>obj9 : { [x: `foo${string}`]: string | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +}; + +const obj12 = { +>obj12 : { [x: `foo${string}`]: string | number | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ ...obj9, [pattern1]: 100,} : { [x: `foo${string}`]: string | number | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ...obj9, +>obj9 : { [x: `foo${string}`]: string | boolean; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: 100, +>[pattern1] : number +> : ^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>100 : 100 +> : ^^^ + +}; + +const obj13 = { +>obj13 : {} +> : ^^ +>{ [pattern1]: 100, ...{ [pattern2]: "hello", },} : {} +> : ^^ + + [pattern1]: 100, +>[pattern1] : number +> : ^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>100 : 100 +> : ^^^ + + ...{ +>{ [pattern2]: "hello", } : { [x: `foobar${string}`]: string; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern2]: "hello", +>[pattern2] : string +> : ^^^^^^ +>pattern2 : `foobar${string}` +> : ^^^^^^^^^^^^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + + }, +}; + +const obj14 = { +>obj14 : { [x: `foo${string}`]: string | number | boolean | number[]; foobarrrrr: number[]; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [pattern1]: 100, ...{ [pattern1]: true, [pattern2]: "hello", foobarrrrr: [1, 2, 3], },} : { [x: `foo${string}`]: string | number | boolean | number[]; foobarrrrr: number[]; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: 100, +>[pattern1] : number +> : ^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>100 : 100 +> : ^^^ + + ...{ +>{ [pattern1]: true, [pattern2]: "hello", foobarrrrr: [1, 2, 3], } : { [x: `foo${string}`]: string | boolean | number[]; [x: `foobar${string}`]: string | number[]; foobarrrrr: number[]; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + [pattern1]: true, +>[pattern1] : boolean +> : ^^^^^^^ +>pattern1 : `foo${string}` +> : ^^^^^^^^^^^^^^ +>true : true +> : ^^^^ + + [pattern2]: "hello", +>[pattern2] : string +> : ^^^^^^ +>pattern2 : `foobar${string}` +> : ^^^^^^^^^^^^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + + foobarrrrr: [1, 2, 3], +>foobarrrrr : number[] +> : ^^^^^^^^ +>[1, 2, 3] : number[] +> : ^^^^^^^^ +>1 : 1 +> : ^ +>2 : 2 +> : ^ +>3 : 3 +> : ^ + + }, +}; + +// repro from https://github.com/microsoft/TypeScript/issues/46309 + +interface IDocument_46309 { + name: string; +>name : string +> : ^^^^^^ + + [added_: `added_${string}`]: number[] | undefined; +>added_ : `added_${string}` +> : ^^^^^^^^^^^^^^^^^ +} + +const tech1_46309 = { +>tech1_46309 : { uuid: string; } +> : ^^^^^^^^^^^^^^^^^ +>{ uuid: "70b26275-5096-4e4b-9d50-3c965c9e5073",} : { uuid: string; } +> : ^^^^^^^^^^^^^^^^^ + + uuid: "70b26275-5096-4e4b-9d50-3c965c9e5073", +>uuid : string +> : ^^^^^^ +>"70b26275-5096-4e4b-9d50-3c965c9e5073" : "70b26275-5096-4e4b-9d50-3c965c9e5073" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +}; + +const doc_46309: IDocument_46309 = { +>doc_46309 : IDocument_46309 +> : ^^^^^^^^^^^^^^^ +>{ name: "", [`added_${tech1_46309.uuid}`]: [19700101],} : { [x: string]: string | number[]; name: string; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + name: "", +>name : string +> : ^^^^^^ +>"" : "" +> : ^^ + + [`added_${tech1_46309.uuid}`]: [19700101], +>[`added_${tech1_46309.uuid}`] : number[] +> : ^^^^^^^^ +>`added_${tech1_46309.uuid}` : string +> : ^^^^^^ +>tech1_46309.uuid : string +> : ^^^^^^ +>tech1_46309 : { uuid: string; } +> : ^^^^^^^^^^^^^^^^^ +>uuid : string +> : ^^^^^^ +>[19700101] : number[] +> : ^^^^^^^^ +>19700101 : 19700101 +> : ^^^^^^^^ + +}; + +const doc2_46309: IDocument_46309 = { +>doc2_46309 : IDocument_46309 +> : ^^^^^^^^^^^^^^^ +>{ name: "", [`added_${tech1_46309.uuid}` as const]: [19700101],} : { [x: `added_${string}`]: number[]; name: string; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + name: "", +>name : string +> : ^^^^^^ +>"" : "" +> : ^^ + + [`added_${tech1_46309.uuid}` as const]: [19700101], +>[`added_${tech1_46309.uuid}` as const] : number[] +> : ^^^^^^^^ +>`added_${tech1_46309.uuid}` as const : `added_${string}` +> : ^^^^^^^^^^^^^^^^^ +>`added_${tech1_46309.uuid}` : `added_${string}` +> : ^^^^^^^^^^^^^^^^^ +>tech1_46309.uuid : string +> : ^^^^^^ +>tech1_46309 : { uuid: string; } +> : ^^^^^^^^^^^^^^^^^ +>uuid : string +> : ^^^^^^ +>[19700101] : number[] +> : ^^^^^^^^ +>19700101 : 19700101 +> : ^^^^^^^^ + +}; + +function genericFn1<T extends string>(input: T) { +>genericFn1 : <T extends string>(input: T) => { [x: string]: number; } +> : ^ ^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>input : T +> : ^ + + const genericPattern = `get${input}` as const; +>genericPattern : `get${T}` +> : ^^^^^^^^^ +>`get${input}` as const : `get${T}` +> : ^^^^^^^^^ +>`get${input}` : `get${T}` +> : ^^^^^^^^^ +>input : T +> : ^ + + return { +>{ [genericPattern]: 1, } : { [x: string]: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^ + + [genericPattern]: 1, +>[genericPattern] : number +> : ^^^^^^ +>genericPattern : `get${T}` +> : ^^^^^^^^^ +>1 : 1 +> : ^ + + }; +} + diff --git a/tests/baselines/reference/indexSignatures1.types b/tests/baselines/reference/indexSignatures1.types index c4d108a16a92b..30d7717ec5607 100644 --- a/tests/baselines/reference/indexSignatures1.types +++ b/tests/baselines/reference/indexSignatures1.types @@ -1564,8 +1564,8 @@ type A = Record<IdType, string>; const a: A = { [id]: 'test' } >a : A > : ^ ->{ [id]: 'test' } : { [x: string]: string; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^ +>{ [id]: 'test' } : { [x: `${number}-${number}-${number}-${number}`]: string; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >[id] : string > : ^^^^^^ >id : `${number}-${number}-${number}-${number}` diff --git a/tests/baselines/reference/isolatedDeclarationErrorsObjects.types b/tests/baselines/reference/isolatedDeclarationErrorsObjects.types index d18df7690c852..8c77a4d1afc74 100644 --- a/tests/baselines/reference/isolatedDeclarationErrorsObjects.types +++ b/tests/baselines/reference/isolatedDeclarationErrorsObjects.types @@ -253,9 +253,9 @@ enum E { > : ^^ } export const oWithComputedProperties = { ->oWithComputedProperties : { [x: string]: number; [x: number]: number; 1: number; 2: number; [s]: number; 10: number; } +>oWithComputedProperties : { [x: number]: number; [x: string]: number; 1: number; 2: number; [s]: number; 10: number; } > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->{ [1]: 1, [1 + 3]: 1, [prop(2)]: 2, [s]: 1, [E.V]: 1, [str]: 0,} : { [x: string]: number; [x: number]: number; 1: number; 2: number; [s]: number; 10: number; } +>{ [1]: 1, [1 + 3]: 1, [prop(2)]: 2, [s]: 1, [E.V]: 1, [str]: 0,} : { [x: number]: number; [x: string]: number; 1: number; 2: number; [s]: number; 10: number; } > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [1]: 1, diff --git a/tests/cases/conformance/es6/computedProperties/computedPropertyNamesTemplateLiteralTypes.ts b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesTemplateLiteralTypes.ts new file mode 100644 index 0000000000000..271239665a24b --- /dev/null +++ b/tests/cases/conformance/es6/computedProperties/computedPropertyNamesTemplateLiteralTypes.ts @@ -0,0 +1,112 @@ +// @strict: true +// @target: esnext + +declare const str1: string; +declare const pattern1: `foo${string}`; +declare const pattern2: `foobar${string}`; +declare const samepattern1: `foo${string}`; + +const obj1 = { + [pattern1]: true, +}; + +const obj2 = { + [pattern1]: true, + [str1]: 100, +}; + +const obj3 = { + [str1]: 100, + [pattern1]: true, +}; + +const obj4 = { + [pattern1]: true, + [pattern2]: "hello", +}; + +const obj5 = { + [pattern2]: "hello", + [pattern1]: true, +}; + +const obj6 = { + [pattern1]: true, + [pattern2]: "hello", + other: 100, +}; + +const obj7 = { + [pattern1]: true, + [pattern2]: "hello", + fooooooooo: 100, +}; + +const obj8 = { + [pattern1]: true, + [pattern2]: "hello", + foobarrrrr: 100, +}; + +const obj9 = { + [pattern1]: true, + [samepattern1]: "hello", +}; + +const obj10 = { + [pattern1]: true, +} as const; + +const obj11 = { + [pattern1]: 100, + ...obj9, +}; + +const obj12 = { + ...obj9, + [pattern1]: 100, +}; + +const obj13 = { + [pattern1]: 100, + ...{ + [pattern2]: "hello", + }, +}; + +const obj14 = { + [pattern1]: 100, + ...{ + [pattern1]: true, + [pattern2]: "hello", + foobarrrrr: [1, 2, 3], + }, +}; + +// repro from https://github.com/microsoft/TypeScript/issues/46309 + +interface IDocument_46309 { + name: string; + [added_: `added_${string}`]: number[] | undefined; +} + +const tech1_46309 = { + uuid: "70b26275-5096-4e4b-9d50-3c965c9e5073", +}; + +const doc_46309: IDocument_46309 = { + name: "", + [`added_${tech1_46309.uuid}`]: [19700101], +}; + +const doc2_46309: IDocument_46309 = { + name: "", + [`added_${tech1_46309.uuid}` as const]: [19700101], +}; + +function genericFn1<T extends string>(input: T) { + const genericPattern = `get${input}` as const; + return { + [genericPattern]: 1, + }; +}