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,
+  };
+}