diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fcb93c45dc1dd..c10bec95be42d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23003,6 +23003,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } } + if (sourceFlags & TypeFlags.TemplateLiteral) { + if (arrayIsEqualTo((source as TemplateLiteralType).texts, (target as TemplateLiteralType).texts)) { + const sourceTypes = (source as TemplateLiteralType).types; + const targetTypes = (target as TemplateLiteralType).types; + result = Ternary.True; + for (let i = 0; i < sourceTypes.length; i++) { + if (!(result &= isRelatedTo(sourceTypes[i], targetTypes[i], RecursionFlags.Both, /*reportErrors*/ false))) { + break; + } + } + return result; + } + } + if (sourceFlags & TypeFlags.StringMapping) { + if ((source as StringMappingType).symbol === (target as StringMappingType).symbol) { + return isRelatedTo((source as StringMappingType).type, (target as StringMappingType).type, RecursionFlags.Both, /*reportErrors*/ false); + } + } if (!(sourceFlags & TypeFlags.Object)) { return Ternary.False; } diff --git a/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.js b/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.js new file mode 100644 index 0000000000000..4e6244df8e0e1 --- /dev/null +++ b/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/assignmentToConditionalBrandedStringTemplateOrMapping.ts] //// + +//// [assignmentToConditionalBrandedStringTemplateOrMapping.ts] +let a: (() => T extends `${'a' & { a: 1 }}` ? 1 : 2) = null!; +let b: (() => T extends `${'a' & { a: 1 }}` ? 1 : 2) = null!; + +a = b; + +let c: (() => T extends Uppercase<'a' & { a: 1 }> ? 1 : 2) = null!; +let d: (() => T extends Uppercase<'a' & { a: 1 }> ? 1 : 2) = null!; + +c = d; + + +//// [assignmentToConditionalBrandedStringTemplateOrMapping.js] +var a = null; +var b = null; +a = b; +var c = null; +var d = null; +c = d; diff --git a/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.symbols b/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.symbols new file mode 100644 index 0000000000000..250742a4b1986 --- /dev/null +++ b/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.symbols @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/assignmentToConditionalBrandedStringTemplateOrMapping.ts] //// + +=== assignmentToConditionalBrandedStringTemplateOrMapping.ts === +let a: (() => T extends `${'a' & { a: 1 }}` ? 1 : 2) = null!; +>a : Symbol(a, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 0, 3)) +>T : Symbol(T, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 0, 9)) +>T : Symbol(T, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 0, 9)) +>a : Symbol(a, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 0, 37)) + +let b: (() => T extends `${'a' & { a: 1 }}` ? 1 : 2) = null!; +>b : Symbol(b, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 1, 3)) +>T : Symbol(T, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 1, 9)) +>T : Symbol(T, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 1, 9)) +>a : Symbol(a, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 1, 37)) + +a = b; +>a : Symbol(a, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 0, 3)) +>b : Symbol(b, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 1, 3)) + +let c: (() => T extends Uppercase<'a' & { a: 1 }> ? 1 : 2) = null!; +>c : Symbol(c, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 5, 3)) +>T : Symbol(T, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 5, 9)) +>T : Symbol(T, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 5, 9)) +>Uppercase : Symbol(Uppercase, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 5, 44)) + +let d: (() => T extends Uppercase<'a' & { a: 1 }> ? 1 : 2) = null!; +>d : Symbol(d, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 6, 3)) +>T : Symbol(T, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 6, 9)) +>T : Symbol(T, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 6, 9)) +>Uppercase : Symbol(Uppercase, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 6, 44)) + +c = d; +>c : Symbol(c, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 5, 3)) +>d : Symbol(d, Decl(assignmentToConditionalBrandedStringTemplateOrMapping.ts, 6, 3)) + diff --git a/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.types b/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.types new file mode 100644 index 0000000000000..61dc9b88001e7 --- /dev/null +++ b/tests/baselines/reference/assignmentToConditionalBrandedStringTemplateOrMapping.types @@ -0,0 +1,51 @@ +//// [tests/cases/compiler/assignmentToConditionalBrandedStringTemplateOrMapping.ts] //// + +=== assignmentToConditionalBrandedStringTemplateOrMapping.ts === +let a: (() => T extends `${'a' & { a: 1 }}` ? 1 : 2) = null!; +>a : () => T extends `${"a" & { a: 1; }}` ? 1 : 2 +> : ^ ^^^^^^^ +>a : 1 +> : ^ +>null! : null +> : ^^^^ + +let b: (() => T extends `${'a' & { a: 1 }}` ? 1 : 2) = null!; +>b : () => T extends `${"a" & { a: 1; }}` ? 1 : 2 +> : ^ ^^^^^^^ +>a : 1 +> : ^ +>null! : null +> : ^^^^ + +a = b; +>a = b : () => T extends `${"a" & { a: 1; }}` ? 1 : 2 +> : ^ ^^^^^^^ +>a : () => T extends `${"a" & { a: 1; }}` ? 1 : 2 +> : ^ ^^^^^^^ +>b : () => T extends `${"a" & { a: 1; }}` ? 1 : 2 +> : ^ ^^^^^^^ + +let c: (() => T extends Uppercase<'a' & { a: 1 }> ? 1 : 2) = null!; +>c : () => T extends Uppercase<"a" & { a: 1; }> ? 1 : 2 +> : ^ ^^^^^^^ +>a : 1 +> : ^ +>null! : null +> : ^^^^ + +let d: (() => T extends Uppercase<'a' & { a: 1 }> ? 1 : 2) = null!; +>d : () => T extends Uppercase<"a" & { a: 1; }> ? 1 : 2 +> : ^ ^^^^^^^ +>a : 1 +> : ^ +>null! : null +> : ^^^^ + +c = d; +>c = d : () => T extends Uppercase<"a" & { a: 1; }> ? 1 : 2 +> : ^ ^^^^^^^ +>c : () => T extends Uppercase<"a" & { a: 1; }> ? 1 : 2 +> : ^ ^^^^^^^ +>d : () => T extends Uppercase<"a" & { a: 1; }> ? 1 : 2 +> : ^ ^^^^^^^ + diff --git a/tests/cases/compiler/assignmentToConditionalBrandedStringTemplateOrMapping.ts b/tests/cases/compiler/assignmentToConditionalBrandedStringTemplateOrMapping.ts new file mode 100644 index 0000000000000..475e42e2f138b --- /dev/null +++ b/tests/cases/compiler/assignmentToConditionalBrandedStringTemplateOrMapping.ts @@ -0,0 +1,9 @@ +let a: (() => T extends `${'a' & { a: 1 }}` ? 1 : 2) = null!; +let b: (() => T extends `${'a' & { a: 1 }}` ? 1 : 2) = null!; + +a = b; + +let c: (() => T extends Uppercase<'a' & { a: 1 }> ? 1 : 2) = null!; +let d: (() => T extends Uppercase<'a' & { a: 1 }> ? 1 : 2) = null!; + +c = d;