mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix template literal type relations (#43440)
* Fix template literal relationships * Accept new baselines * Add regression test
This commit is contained in:
+5
-14
@@ -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 && (<StringMappingType>source).symbol === (<StringMappingType>target).symbol) {
|
||||
if (result = isRelatedTo((<StringMappingType>source).type, (<StringMappingType>target).type, reportErrors)) {
|
||||
|
||||
@@ -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<T extends string>(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<T>(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)`);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)`);
|
||||
|
||||
Reference in New Issue
Block a user