diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c6a9f7e75a633..3361ad3f12eb4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18274,6 +18274,11 @@ namespace ts { } } else if (target.flags & TypeFlags.TemplateLiteral) { + if (source.flags & TypeFlags.TemplateLiteral) { + // Report unreliable variance for type variables referenced in template literal type placeholders. + // For example, `foo-${number}` is related to `foo-${string}` even though number isn't related to string. + instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)); + } const result = inferTypesFromTemplateLiteralType(source, target as TemplateLiteralType); if (result && every(result, (r, i) => isValidTypeForTemplateLiteralPlaceholder(r, (target as TemplateLiteralType).types[i]))) { return Ternary.True; @@ -18318,20 +18323,6 @@ namespace ts { return result; } } - else if (source.flags & TypeFlags.TemplateLiteral) { - if (target.flags & TypeFlags.TemplateLiteral && - (source as TemplateLiteralType).texts.length === (target as TemplateLiteralType).texts.length && - (source as TemplateLiteralType).types.length === (target as TemplateLiteralType).types.length && - every((source as TemplateLiteralType).texts, (t, i) => t === (target as TemplateLiteralType).texts[i]) && - every((instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)) as TemplateLiteralType).types, (t, i) => !!((target as TemplateLiteralType).types[i].flags & (TypeFlags.Any | TypeFlags.String)) || !!isRelatedTo(t, (target as TemplateLiteralType).types[i], /*reportErrors*/ false))) { - return Ternary.True; - } - const constraint = getBaseConstraintOfType(source); - if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, reportErrors))) { - resetErrorInfo(saveErrorInfo); - return result; - } - } else if (source.flags & TypeFlags.StringMapping) { if (target.flags & TypeFlags.StringMapping && (source).symbol === (target).symbol) { if (result = isRelatedTo((source).type, (target).type, reportErrors)) { diff --git a/tests/baselines/reference/templateLiteralTypes2.errors.txt b/tests/baselines/reference/templateLiteralTypes2.errors.txt index 662b6704d6352..7e9308d47e659 100644 --- a/tests/baselines/reference/templateLiteralTypes2.errors.txt +++ b/tests/baselines/reference/templateLiteralTypes2.errors.txt @@ -1,13 +1,9 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(23,11): error TS2322: Type 'string' is not assignable to type '`abc${string}`'. tests/cases/conformance/types/literal/templateLiteralTypes2.ts(29,11): error TS2322: Type 'string' is not assignable to type '`foo${string}` | `bar${string}`'. tests/cases/conformance/types/literal/templateLiteralTypes2.ts(32,11): error TS2322: Type 'string' is not assignable to type '`foo${string}` | `bar${string}` | `baz${string}`'. -tests/cases/conformance/types/literal/templateLiteralTypes2.ts(67,9): error TS2322: Type '`foo${number}`' is not assignable to type 'String'. -tests/cases/conformance/types/literal/templateLiteralTypes2.ts(68,9): error TS2322: Type '`foo${number}`' is not assignable to type 'Object'. -tests/cases/conformance/types/literal/templateLiteralTypes2.ts(69,9): error TS2322: Type '`foo${number}`' is not assignable to type '{}'. -tests/cases/conformance/types/literal/templateLiteralTypes2.ts(70,9): error TS2322: Type '`foo${number}`' is not assignable to type '{ length: number; }'. -==== tests/cases/conformance/types/literal/templateLiteralTypes2.ts (7 errors) ==== +==== tests/cases/conformance/types/literal/templateLiteralTypes2.ts (3 errors) ==== function ft1(s: string, n: number, u: 'foo' | 'bar' | 'baz', t: T) { const c1 = `abc${s}`; // `abc${string}` const c2 = `abc${n}`; // `abc${number}` @@ -81,17 +77,9 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(70,9): error TS23 function ft14(t: `foo${number}`) { let x1: string = t; let x2: String = t; - ~~ -!!! error TS2322: Type '`foo${number}`' is not assignable to type 'String'. let x3: Object = t; - ~~ -!!! error TS2322: Type '`foo${number}`' is not assignable to type 'Object'. let x4: {} = t; - ~~ -!!! error TS2322: Type '`foo${number}`' is not assignable to type '{}'. let x6: { length: number } = t; - ~~ -!!! error TS2322: Type '`foo${number}`' is not assignable to type '{ length: number; }'. } declare function g1(x: T): T; @@ -134,4 +122,10 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(70,9): error TS23 function getCardTitle(title: string): `test-${string}` { return `test-${title}`; } + + // Repro from #43424 + + const interpolatedStyle = { rotate: 12 }; + function C2(transform: "-moz-initial" | (string & {})) { return 12; } + C2(`rotate(${interpolatedStyle.rotate}dig)`); \ No newline at end of file diff --git a/tests/baselines/reference/templateLiteralTypes2.js b/tests/baselines/reference/templateLiteralTypes2.js index 87be2dbe4fa76..37c101be26923 100644 --- a/tests/baselines/reference/templateLiteralTypes2.js +++ b/tests/baselines/reference/templateLiteralTypes2.js @@ -111,6 +111,12 @@ const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`; function getCardTitle(title: string): `test-${string}` { return `test-${title}`; } + +// Repro from #43424 + +const interpolatedStyle = { rotate: 12 }; +function C2(transform: "-moz-initial" | (string & {})) { return 12; } +C2(`rotate(${interpolatedStyle.rotate}dig)`); //// [templateLiteralTypes2.js] @@ -194,6 +200,10 @@ var pixelStringWithTemplate = pixelValue + "px"; function getCardTitle(title) { return "test-" + title; } +// Repro from #43424 +var interpolatedStyle = { rotate: 12 }; +function C2(transform) { return 12; } +C2("rotate(" + interpolatedStyle.rotate + "dig)"); //// [templateLiteralTypes2.d.ts] @@ -225,3 +235,7 @@ declare type PixelValueType = `${number}px`; declare const pixelString: PixelValueType; declare const pixelStringWithTemplate: PixelValueType; declare function getCardTitle(title: string): `test-${string}`; +declare const interpolatedStyle: { + rotate: number; +}; +declare function C2(transform: "-moz-initial" | (string & {})): number; diff --git a/tests/baselines/reference/templateLiteralTypes2.symbols b/tests/baselines/reference/templateLiteralTypes2.symbols index 6348ebce7f95b..4ac9d428a0618 100644 --- a/tests/baselines/reference/templateLiteralTypes2.symbols +++ b/tests/baselines/reference/templateLiteralTypes2.symbols @@ -361,3 +361,19 @@ function getCardTitle(title: string): `test-${string}` { >title : Symbol(title, Decl(templateLiteralTypes2.ts, 109, 22)) } +// Repro from #43424 + +const interpolatedStyle = { rotate: 12 }; +>interpolatedStyle : Symbol(interpolatedStyle, Decl(templateLiteralTypes2.ts, 115, 5)) +>rotate : Symbol(rotate, Decl(templateLiteralTypes2.ts, 115, 27)) + +function C2(transform: "-moz-initial" | (string & {})) { return 12; } +>C2 : Symbol(C2, Decl(templateLiteralTypes2.ts, 115, 41)) +>transform : Symbol(transform, Decl(templateLiteralTypes2.ts, 116, 12)) + +C2(`rotate(${interpolatedStyle.rotate}dig)`); +>C2 : Symbol(C2, Decl(templateLiteralTypes2.ts, 115, 41)) +>interpolatedStyle.rotate : Symbol(rotate, Decl(templateLiteralTypes2.ts, 115, 27)) +>interpolatedStyle : Symbol(interpolatedStyle, Decl(templateLiteralTypes2.ts, 115, 5)) +>rotate : Symbol(rotate, Decl(templateLiteralTypes2.ts, 115, 27)) + diff --git a/tests/baselines/reference/templateLiteralTypes2.types b/tests/baselines/reference/templateLiteralTypes2.types index 274e3eb4f0b1b..24096c9d782ec 100644 --- a/tests/baselines/reference/templateLiteralTypes2.types +++ b/tests/baselines/reference/templateLiteralTypes2.types @@ -392,3 +392,24 @@ function getCardTitle(title: string): `test-${string}` { >title : string } +// Repro from #43424 + +const interpolatedStyle = { rotate: 12 }; +>interpolatedStyle : { rotate: number; } +>{ rotate: 12 } : { rotate: number; } +>rotate : number +>12 : 12 + +function C2(transform: "-moz-initial" | (string & {})) { return 12; } +>C2 : (transform: "-moz-initial" | (string & {})) => number +>transform : (string & {}) | "-moz-initial" +>12 : 12 + +C2(`rotate(${interpolatedStyle.rotate}dig)`); +>C2(`rotate(${interpolatedStyle.rotate}dig)`) : number +>C2 : (transform: (string & {}) | "-moz-initial") => number +>`rotate(${interpolatedStyle.rotate}dig)` : `rotate(${number}dig)` +>interpolatedStyle.rotate : number +>interpolatedStyle : { rotate: number; } +>rotate : number + diff --git a/tests/cases/conformance/types/literal/templateLiteralTypes2.ts b/tests/cases/conformance/types/literal/templateLiteralTypes2.ts index 75ab1485a05fa..5e51c5b30b227 100644 --- a/tests/cases/conformance/types/literal/templateLiteralTypes2.ts +++ b/tests/cases/conformance/types/literal/templateLiteralTypes2.ts @@ -113,3 +113,9 @@ const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`; function getCardTitle(title: string): `test-${string}` { return `test-${title}`; } + +// Repro from #43424 + +const interpolatedStyle = { rotate: 12 }; +function C2(transform: "-moz-initial" | (string & {})) { return 12; } +C2(`rotate(${interpolatedStyle.rotate}dig)`);