mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
Template literal types for contextually typed template literal expressions (#43376)
* Template literal types for contextually typed template literal expressions * Accept new baselines * Add regression test * Add a few more tests
This commit is contained in:
@@ -31824,7 +31824,12 @@ namespace ts {
|
||||
texts.push(span.literal.text);
|
||||
types.push(isTypeAssignableTo(type, templateConstraintType) ? type : stringType);
|
||||
}
|
||||
return isConstContext(node) ? getTemplateLiteralType(texts, types) : stringType;
|
||||
return isConstContext(node) || someType(getContextualType(node) || unknownType, isTemplateLiteralContextualType) ? getTemplateLiteralType(texts, types) : stringType;
|
||||
}
|
||||
|
||||
function isTemplateLiteralContextualType(type: Type): boolean {
|
||||
return !!(type.flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral) ||
|
||||
type.flags & TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, TypeFlags.StringLike));
|
||||
}
|
||||
|
||||
function getContextNode(node: Expression): Node {
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
tests/cases/conformance/types/stringLiteral/stringLiteralTypesWithTemplateStrings02.ts(1,5): error TS2322: Type '"AB\nC"' is not assignable to type '"AB\r\nC"'.
|
||||
tests/cases/conformance/types/stringLiteral/stringLiteralTypesWithTemplateStrings02.ts(3,5): error TS2322: Type 'string' is not assignable to type '"DE\nF"'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesWithTemplateStrings02.ts (2 errors) ====
|
||||
==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesWithTemplateStrings02.ts (1 errors) ====
|
||||
let abc: "AB\r\nC" = `AB
|
||||
~~~
|
||||
!!! error TS2322: Type '"AB\nC"' is not assignable to type '"AB\r\nC"'.
|
||||
C`;
|
||||
let de_NEWLINE_f: "DE\nF" = `DE${"\n"}F`;
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '"DE\nF"'.
|
||||
let de_NEWLINE_f: "DE\nF" = `DE${"\n"}F`;
|
||||
@@ -6,6 +6,6 @@ let abc: "AB\r\nC" = `AB
|
||||
C`;
|
||||
let de_NEWLINE_f: "DE\nF" = `DE${"\n"}F`;
|
||||
>de_NEWLINE_f : "DE\nF"
|
||||
>`DE${"\n"}F` : string
|
||||
>`DE${"\n"}F` : "DE\nF"
|
||||
>"\n" : "\n"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ const createScopedActionType = <S extends string>(scope: S) => <T extends string
|
||||
><T extends string>(type: T) => `${scope}/${type}` as `${S}/${T}` : <T extends string>(type: T) => `${S}/${T}`
|
||||
>type : T
|
||||
>`${scope}/${type}` as `${S}/${T}` : `${S}/${T}`
|
||||
>`${scope}/${type}` : string
|
||||
>`${scope}/${type}` : `${S}/${T}`
|
||||
>scope : S
|
||||
>type : T
|
||||
|
||||
|
||||
@@ -1,37 +1,22 @@
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes2.ts(6,11): error TS2322: Type 'string' is not assignable to type '`abc${string}`'.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes2.ts(7,11): error TS2322: Type 'string' is not assignable to type '`abc${number}`'.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes2.ts(8,11): error TS2322: Type 'string' is not assignable to type '"abcfoo" | "abcbar" | "abcbaz"'.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes2.ts(9,11): error TS2322: Type 'string' is not assignable to type '`abc${T}`'.
|
||||
tests/cases/conformance/types/literal/templateLiteralTypes2.ts(21,11): error TS2322: Type 'string' is not assignable to type '`abc${string}`'.
|
||||
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(43,11): error TS2322: Type 'string' is not assignable to type '`foo${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(98,7): error TS2322: Type 'string' is not assignable to type '`${number}px`'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/literal/templateLiteralTypes2.ts (14 errors) ====
|
||||
==== tests/cases/conformance/types/literal/templateLiteralTypes2.ts (7 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}`
|
||||
const c3 = `abc${u}`; // "abcfoo" | "abcbar" | "abcbaz"
|
||||
const c4 = `abc${t}`; // `abc${T}
|
||||
const d1: `abc${string}` = `abc${s}`;
|
||||
~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '`abc${string}`'.
|
||||
const d2: `abc${number}` = `abc${n}`;
|
||||
~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '`abc${number}`'.
|
||||
const d3: `abc${'foo' | 'bar' | 'baz'}` = `abc${u}`;
|
||||
~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '"abcfoo" | "abcbar" | "abcbaz"'.
|
||||
const d4: `abc${T}` = `abc${t}`;
|
||||
~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '`abc${T}`'.
|
||||
}
|
||||
|
||||
function ft2(s: string) {
|
||||
@@ -44,8 +29,6 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(98,7): error TS23
|
||||
const c2 = c1; // Widening type `abc${string}`
|
||||
let v2 = c2; // Type string
|
||||
const c3: `abc${string}` = `abc${s}`;
|
||||
~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '`abc${string}`'.
|
||||
let v3 = c3; // Type `abc${string}`
|
||||
const c4: `abc${string}` = c1; // Type `abc${string}`
|
||||
~~
|
||||
@@ -74,8 +57,6 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(98,7): error TS23
|
||||
const c1 = `foo${s}`;
|
||||
let v1 = c1;
|
||||
const c2: `foo${string}` = `foo${s}`;
|
||||
~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '`foo${string}`'.
|
||||
let v2 = c2;
|
||||
const c3 = `foo${s}` as `foo${string}`;
|
||||
let v3 = c3;
|
||||
@@ -113,6 +94,14 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(98,7): error TS23
|
||||
!!! error TS2322: Type '`foo${number}`' is not assignable to type '{ length: number; }'.
|
||||
}
|
||||
|
||||
declare function g1<T>(x: T): T;
|
||||
declare function g2<T extends string>(x: T): T;
|
||||
|
||||
function ft20(s: string) {
|
||||
let x1 = g1(`xyz-${s}`); // string
|
||||
let x2 = g2(`xyz-${s}`); // `xyz-${string}`
|
||||
}
|
||||
|
||||
// Repro from #41631
|
||||
|
||||
declare function takesLiteral<T extends string>(literal: T): T extends `foo.bar.${infer R}` ? R : unknown;
|
||||
@@ -139,6 +128,10 @@ tests/cases/conformance/types/literal/templateLiteralTypes2.ts(98,7): error TS23
|
||||
const pixelString: PixelValueType = `22px`;
|
||||
|
||||
const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '`${number}px`'.
|
||||
|
||||
// Repro from #43143
|
||||
|
||||
function getCardTitle(title: string): `test-${string}` {
|
||||
return `test-${title}`;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,14 @@ function ft14(t: `foo${number}`) {
|
||||
let x6: { length: number } = t;
|
||||
}
|
||||
|
||||
declare function g1<T>(x: T): T;
|
||||
declare function g2<T extends string>(x: T): T;
|
||||
|
||||
function ft20(s: string) {
|
||||
let x1 = g1(`xyz-${s}`); // string
|
||||
let x2 = g2(`xyz-${s}`); // `xyz-${string}`
|
||||
}
|
||||
|
||||
// Repro from #41631
|
||||
|
||||
declare function takesLiteral<T extends string>(literal: T): T extends `foo.bar.${infer R}` ? R : unknown;
|
||||
@@ -97,6 +105,12 @@ type PixelValueType = `${number}px`;
|
||||
const pixelString: PixelValueType = `22px`;
|
||||
|
||||
const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`;
|
||||
|
||||
// Repro from #43143
|
||||
|
||||
function getCardTitle(title: string): `test-${string}` {
|
||||
return `test-${title}`;
|
||||
}
|
||||
|
||||
|
||||
//// [templateLiteralTypes2.js]
|
||||
@@ -161,6 +175,10 @@ function ft14(t) {
|
||||
var x4 = t;
|
||||
var x6 = t;
|
||||
}
|
||||
function ft20(s) {
|
||||
var x1 = g1("xyz-" + s); // string
|
||||
var x2 = g2("xyz-" + s); // `xyz-${string}`
|
||||
}
|
||||
var t1 = takesLiteral("foo.bar.baz"); // "baz"
|
||||
var id2 = "foo.bar.baz";
|
||||
var t2 = takesLiteral(id2); // "baz"
|
||||
@@ -172,6 +190,10 @@ var t5 = takesLiteral("foo.bar." + someUnion); // "abc" | "def" | "ghi"
|
||||
var pixelValue = 22;
|
||||
var pixelString = "22px";
|
||||
var pixelStringWithTemplate = pixelValue + "px";
|
||||
// Repro from #43143
|
||||
function getCardTitle(title) {
|
||||
return "test-" + title;
|
||||
}
|
||||
|
||||
|
||||
//// [templateLiteralTypes2.d.ts]
|
||||
@@ -185,17 +207,21 @@ declare function nonWidening<T extends string | number | symbol>(x: T): T;
|
||||
declare function ft13(s: string, cond: boolean): void;
|
||||
declare type T0 = string | `${number}px`;
|
||||
declare function ft14(t: `foo${number}`): void;
|
||||
declare function g1<T>(x: T): T;
|
||||
declare function g2<T extends string>(x: T): T;
|
||||
declare function ft20(s: string): void;
|
||||
declare function takesLiteral<T extends string>(literal: T): T extends `foo.bar.${infer R}` ? R : unknown;
|
||||
declare const t1: "baz";
|
||||
declare const id2 = "foo.bar.baz";
|
||||
declare const t2: "baz";
|
||||
declare const someString: string;
|
||||
declare const t3: unknown;
|
||||
declare const t3: string;
|
||||
declare const id4: string;
|
||||
declare const t4: unknown;
|
||||
declare const someUnion: 'abc' | 'def' | 'ghi';
|
||||
declare const t5: unknown;
|
||||
declare const t5: "abc" | "def" | "ghi";
|
||||
declare const pixelValue: number;
|
||||
declare type PixelValueType = `${number}px`;
|
||||
declare const pixelString: PixelValueType;
|
||||
declare const pixelStringWithTemplate: PixelValueType;
|
||||
declare function getCardTitle(title: string): `test-${string}`;
|
||||
|
||||
@@ -257,68 +257,107 @@ function ft14(t: `foo${number}`) {
|
||||
>t : Symbol(t, Decl(templateLiteralTypes2.ts, 64, 14))
|
||||
}
|
||||
|
||||
declare function g1<T>(x: T): T;
|
||||
>g1 : Symbol(g1, Decl(templateLiteralTypes2.ts, 70, 1))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 72, 20))
|
||||
>x : Symbol(x, Decl(templateLiteralTypes2.ts, 72, 23))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 72, 20))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 72, 20))
|
||||
|
||||
declare function g2<T extends string>(x: T): T;
|
||||
>g2 : Symbol(g2, Decl(templateLiteralTypes2.ts, 72, 32))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 73, 20))
|
||||
>x : Symbol(x, Decl(templateLiteralTypes2.ts, 73, 38))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 73, 20))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 73, 20))
|
||||
|
||||
function ft20(s: string) {
|
||||
>ft20 : Symbol(ft20, Decl(templateLiteralTypes2.ts, 73, 47))
|
||||
>s : Symbol(s, Decl(templateLiteralTypes2.ts, 75, 14))
|
||||
|
||||
let x1 = g1(`xyz-${s}`); // string
|
||||
>x1 : Symbol(x1, Decl(templateLiteralTypes2.ts, 76, 7))
|
||||
>g1 : Symbol(g1, Decl(templateLiteralTypes2.ts, 70, 1))
|
||||
>s : Symbol(s, Decl(templateLiteralTypes2.ts, 75, 14))
|
||||
|
||||
let x2 = g2(`xyz-${s}`); // `xyz-${string}`
|
||||
>x2 : Symbol(x2, Decl(templateLiteralTypes2.ts, 77, 7))
|
||||
>g2 : Symbol(g2, Decl(templateLiteralTypes2.ts, 72, 32))
|
||||
>s : Symbol(s, Decl(templateLiteralTypes2.ts, 75, 14))
|
||||
}
|
||||
|
||||
// Repro from #41631
|
||||
|
||||
declare function takesLiteral<T extends string>(literal: T): T extends `foo.bar.${infer R}` ? R : unknown;
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 70, 1))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 74, 30))
|
||||
>literal : Symbol(literal, Decl(templateLiteralTypes2.ts, 74, 48))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 74, 30))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 74, 30))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes2.ts, 74, 87))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes2.ts, 74, 87))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 78, 1))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 82, 30))
|
||||
>literal : Symbol(literal, Decl(templateLiteralTypes2.ts, 82, 48))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 82, 30))
|
||||
>T : Symbol(T, Decl(templateLiteralTypes2.ts, 82, 30))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes2.ts, 82, 87))
|
||||
>R : Symbol(R, Decl(templateLiteralTypes2.ts, 82, 87))
|
||||
|
||||
const t1 = takesLiteral("foo.bar.baz"); // "baz"
|
||||
>t1 : Symbol(t1, Decl(templateLiteralTypes2.ts, 76, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 70, 1))
|
||||
>t1 : Symbol(t1, Decl(templateLiteralTypes2.ts, 84, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 78, 1))
|
||||
|
||||
const id2 = "foo.bar.baz";
|
||||
>id2 : Symbol(id2, Decl(templateLiteralTypes2.ts, 77, 5))
|
||||
>id2 : Symbol(id2, Decl(templateLiteralTypes2.ts, 85, 5))
|
||||
|
||||
const t2 = takesLiteral(id2); // "baz"
|
||||
>t2 : Symbol(t2, Decl(templateLiteralTypes2.ts, 78, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 70, 1))
|
||||
>id2 : Symbol(id2, Decl(templateLiteralTypes2.ts, 77, 5))
|
||||
>t2 : Symbol(t2, Decl(templateLiteralTypes2.ts, 86, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 78, 1))
|
||||
>id2 : Symbol(id2, Decl(templateLiteralTypes2.ts, 85, 5))
|
||||
|
||||
declare const someString: string;
|
||||
>someString : Symbol(someString, Decl(templateLiteralTypes2.ts, 80, 13))
|
||||
>someString : Symbol(someString, Decl(templateLiteralTypes2.ts, 88, 13))
|
||||
|
||||
const t3 = takesLiteral(`foo.bar.${someString}`); // string
|
||||
>t3 : Symbol(t3, Decl(templateLiteralTypes2.ts, 81, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 70, 1))
|
||||
>someString : Symbol(someString, Decl(templateLiteralTypes2.ts, 80, 13))
|
||||
>t3 : Symbol(t3, Decl(templateLiteralTypes2.ts, 89, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 78, 1))
|
||||
>someString : Symbol(someString, Decl(templateLiteralTypes2.ts, 88, 13))
|
||||
|
||||
const id4 = `foo.bar.${someString}`;
|
||||
>id4 : Symbol(id4, Decl(templateLiteralTypes2.ts, 83, 5))
|
||||
>someString : Symbol(someString, Decl(templateLiteralTypes2.ts, 80, 13))
|
||||
>id4 : Symbol(id4, Decl(templateLiteralTypes2.ts, 91, 5))
|
||||
>someString : Symbol(someString, Decl(templateLiteralTypes2.ts, 88, 13))
|
||||
|
||||
const t4 = takesLiteral(id4); // string
|
||||
>t4 : Symbol(t4, Decl(templateLiteralTypes2.ts, 84, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 70, 1))
|
||||
>id4 : Symbol(id4, Decl(templateLiteralTypes2.ts, 83, 5))
|
||||
>t4 : Symbol(t4, Decl(templateLiteralTypes2.ts, 92, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 78, 1))
|
||||
>id4 : Symbol(id4, Decl(templateLiteralTypes2.ts, 91, 5))
|
||||
|
||||
declare const someUnion: 'abc' | 'def' | 'ghi';
|
||||
>someUnion : Symbol(someUnion, Decl(templateLiteralTypes2.ts, 86, 13))
|
||||
>someUnion : Symbol(someUnion, Decl(templateLiteralTypes2.ts, 94, 13))
|
||||
|
||||
const t5 = takesLiteral(`foo.bar.${someUnion}`); // "abc" | "def" | "ghi"
|
||||
>t5 : Symbol(t5, Decl(templateLiteralTypes2.ts, 87, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 70, 1))
|
||||
>someUnion : Symbol(someUnion, Decl(templateLiteralTypes2.ts, 86, 13))
|
||||
>t5 : Symbol(t5, Decl(templateLiteralTypes2.ts, 95, 5))
|
||||
>takesLiteral : Symbol(takesLiteral, Decl(templateLiteralTypes2.ts, 78, 1))
|
||||
>someUnion : Symbol(someUnion, Decl(templateLiteralTypes2.ts, 94, 13))
|
||||
|
||||
// Repro from #41732
|
||||
|
||||
const pixelValue: number = 22;
|
||||
>pixelValue : Symbol(pixelValue, Decl(templateLiteralTypes2.ts, 91, 5))
|
||||
>pixelValue : Symbol(pixelValue, Decl(templateLiteralTypes2.ts, 99, 5))
|
||||
|
||||
type PixelValueType = `${number}px`;
|
||||
>PixelValueType : Symbol(PixelValueType, Decl(templateLiteralTypes2.ts, 91, 30))
|
||||
>PixelValueType : Symbol(PixelValueType, Decl(templateLiteralTypes2.ts, 99, 30))
|
||||
|
||||
const pixelString: PixelValueType = `22px`;
|
||||
>pixelString : Symbol(pixelString, Decl(templateLiteralTypes2.ts, 95, 5))
|
||||
>PixelValueType : Symbol(PixelValueType, Decl(templateLiteralTypes2.ts, 91, 30))
|
||||
>pixelString : Symbol(pixelString, Decl(templateLiteralTypes2.ts, 103, 5))
|
||||
>PixelValueType : Symbol(PixelValueType, Decl(templateLiteralTypes2.ts, 99, 30))
|
||||
|
||||
const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`;
|
||||
>pixelStringWithTemplate : Symbol(pixelStringWithTemplate, Decl(templateLiteralTypes2.ts, 97, 5))
|
||||
>PixelValueType : Symbol(PixelValueType, Decl(templateLiteralTypes2.ts, 91, 30))
|
||||
>pixelValue : Symbol(pixelValue, Decl(templateLiteralTypes2.ts, 91, 5))
|
||||
>pixelStringWithTemplate : Symbol(pixelStringWithTemplate, Decl(templateLiteralTypes2.ts, 105, 5))
|
||||
>PixelValueType : Symbol(PixelValueType, Decl(templateLiteralTypes2.ts, 99, 30))
|
||||
>pixelValue : Symbol(pixelValue, Decl(templateLiteralTypes2.ts, 99, 5))
|
||||
|
||||
// Repro from #43143
|
||||
|
||||
function getCardTitle(title: string): `test-${string}` {
|
||||
>getCardTitle : Symbol(getCardTitle, Decl(templateLiteralTypes2.ts, 105, 66))
|
||||
>title : Symbol(title, Decl(templateLiteralTypes2.ts, 109, 22))
|
||||
|
||||
return `test-${title}`;
|
||||
>title : Symbol(title, Decl(templateLiteralTypes2.ts, 109, 22))
|
||||
}
|
||||
|
||||
|
||||
@@ -28,22 +28,22 @@ function ft1<T extends string>(s: string, n: number, u: 'foo' | 'bar' | 'baz', t
|
||||
|
||||
const d1: `abc${string}` = `abc${s}`;
|
||||
>d1 : `abc${string}`
|
||||
>`abc${s}` : string
|
||||
>`abc${s}` : `abc${string}`
|
||||
>s : string
|
||||
|
||||
const d2: `abc${number}` = `abc${n}`;
|
||||
>d2 : `abc${number}`
|
||||
>`abc${n}` : string
|
||||
>`abc${n}` : `abc${number}`
|
||||
>n : number
|
||||
|
||||
const d3: `abc${'foo' | 'bar' | 'baz'}` = `abc${u}`;
|
||||
>d3 : "abcfoo" | "abcbar" | "abcbaz"
|
||||
>`abc${u}` : string
|
||||
>`abc${u}` : "abcfoo" | "abcbar" | "abcbaz"
|
||||
>u : "foo" | "bar" | "baz"
|
||||
|
||||
const d4: `abc${T}` = `abc${t}`;
|
||||
>d4 : `abc${T}`
|
||||
>`abc${t}` : string
|
||||
>`abc${t}` : `abc${T}`
|
||||
>t : T
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ function ft10(s: string) {
|
||||
|
||||
const c3: `abc${string}` = `abc${s}`;
|
||||
>c3 : `abc${string}`
|
||||
>`abc${s}` : string
|
||||
>`abc${s}` : `abc${string}`
|
||||
>s : string
|
||||
|
||||
let v3 = c3; // Type `abc${string}`
|
||||
@@ -168,7 +168,7 @@ function ft12(s: string) {
|
||||
|
||||
const c2: `foo${string}` = `foo${s}`;
|
||||
>c2 : `foo${string}`
|
||||
>`foo${s}` : string
|
||||
>`foo${s}` : `foo${string}`
|
||||
>s : string
|
||||
|
||||
let v2 = c2;
|
||||
@@ -178,7 +178,7 @@ function ft12(s: string) {
|
||||
const c3 = `foo${s}` as `foo${string}`;
|
||||
>c3 : `foo${string}`
|
||||
>`foo${s}` as `foo${string}` : `foo${string}`
|
||||
>`foo${s}` : string
|
||||
>`foo${s}` : `foo${string}`
|
||||
>s : string
|
||||
|
||||
let v3 = c3;
|
||||
@@ -188,7 +188,7 @@ function ft12(s: string) {
|
||||
const c4 = <`foo${string}`>`foo${s}`;
|
||||
>c4 : `foo${string}`
|
||||
><`foo${string}`>`foo${s}` : `foo${string}`
|
||||
>`foo${s}` : string
|
||||
>`foo${s}` : `foo${string}`
|
||||
>s : string
|
||||
|
||||
let v4 = c4;
|
||||
@@ -237,20 +237,20 @@ function ft13(s: string, cond: boolean) {
|
||||
>s : string
|
||||
|
||||
let y1 = nonWidening(`foo${s}`);
|
||||
>y1 : string
|
||||
>nonWidening(`foo${s}`) : string
|
||||
>y1 : `foo${string}`
|
||||
>nonWidening(`foo${s}`) : `foo${string}`
|
||||
>nonWidening : <T extends string | number | symbol>(x: T) => T
|
||||
>`foo${s}` : string
|
||||
>`foo${s}` : `foo${string}`
|
||||
>s : string
|
||||
|
||||
let y2 = nonWidening(cond ? 'a' : `foo${s}`);
|
||||
>y2 : string
|
||||
>nonWidening(cond ? 'a' : `foo${s}`) : string
|
||||
>y2 : `foo${string}` | "a"
|
||||
>nonWidening(cond ? 'a' : `foo${s}`) : `foo${string}` | "a"
|
||||
>nonWidening : <T extends string | number | symbol>(x: T) => T
|
||||
>cond ? 'a' : `foo${s}` : string
|
||||
>cond ? 'a' : `foo${s}` : `foo${string}` | "a"
|
||||
>cond : boolean
|
||||
>'a' : "a"
|
||||
>`foo${s}` : string
|
||||
>`foo${s}` : `foo${string}`
|
||||
>s : string
|
||||
}
|
||||
|
||||
@@ -283,6 +283,33 @@ function ft14(t: `foo${number}`) {
|
||||
>t : `foo${number}`
|
||||
}
|
||||
|
||||
declare function g1<T>(x: T): T;
|
||||
>g1 : <T>(x: T) => T
|
||||
>x : T
|
||||
|
||||
declare function g2<T extends string>(x: T): T;
|
||||
>g2 : <T extends string>(x: T) => T
|
||||
>x : T
|
||||
|
||||
function ft20(s: string) {
|
||||
>ft20 : (s: string) => void
|
||||
>s : string
|
||||
|
||||
let x1 = g1(`xyz-${s}`); // string
|
||||
>x1 : string
|
||||
>g1(`xyz-${s}`) : string
|
||||
>g1 : <T>(x: T) => T
|
||||
>`xyz-${s}` : string
|
||||
>s : string
|
||||
|
||||
let x2 = g2(`xyz-${s}`); // `xyz-${string}`
|
||||
>x2 : `xyz-${string}`
|
||||
>g2(`xyz-${s}`) : `xyz-${string}`
|
||||
>g2 : <T extends string>(x: T) => T
|
||||
>`xyz-${s}` : `xyz-${string}`
|
||||
>s : string
|
||||
}
|
||||
|
||||
// Repro from #41631
|
||||
|
||||
declare function takesLiteral<T extends string>(literal: T): T extends `foo.bar.${infer R}` ? R : unknown;
|
||||
@@ -309,10 +336,10 @@ declare const someString: string;
|
||||
>someString : string
|
||||
|
||||
const t3 = takesLiteral(`foo.bar.${someString}`); // string
|
||||
>t3 : unknown
|
||||
>takesLiteral(`foo.bar.${someString}`) : unknown
|
||||
>t3 : string
|
||||
>takesLiteral(`foo.bar.${someString}`) : string
|
||||
>takesLiteral : <T extends string>(literal: T) => T extends `foo.bar.${infer R}` ? R : unknown
|
||||
>`foo.bar.${someString}` : string
|
||||
>`foo.bar.${someString}` : `foo.bar.${string}`
|
||||
>someString : string
|
||||
|
||||
const id4 = `foo.bar.${someString}`;
|
||||
@@ -330,10 +357,10 @@ declare const someUnion: 'abc' | 'def' | 'ghi';
|
||||
>someUnion : "abc" | "def" | "ghi"
|
||||
|
||||
const t5 = takesLiteral(`foo.bar.${someUnion}`); // "abc" | "def" | "ghi"
|
||||
>t5 : unknown
|
||||
>takesLiteral(`foo.bar.${someUnion}`) : unknown
|
||||
>t5 : "abc" | "def" | "ghi"
|
||||
>takesLiteral(`foo.bar.${someUnion}`) : "abc" | "def" | "ghi"
|
||||
>takesLiteral : <T extends string>(literal: T) => T extends `foo.bar.${infer R}` ? R : unknown
|
||||
>`foo.bar.${someUnion}` : string
|
||||
>`foo.bar.${someUnion}` : "foo.bar.abc" | "foo.bar.def" | "foo.bar.ghi"
|
||||
>someUnion : "abc" | "def" | "ghi"
|
||||
|
||||
// Repro from #41732
|
||||
@@ -351,6 +378,17 @@ const pixelString: PixelValueType = `22px`;
|
||||
|
||||
const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`;
|
||||
>pixelStringWithTemplate : `${number}px`
|
||||
>`${pixelValue}px` : string
|
||||
>`${pixelValue}px` : `${number}px`
|
||||
>pixelValue : number
|
||||
|
||||
// Repro from #43143
|
||||
|
||||
function getCardTitle(title: string): `test-${string}` {
|
||||
>getCardTitle : (title: string) => `test-${string}`
|
||||
>title : string
|
||||
|
||||
return `test-${title}`;
|
||||
>`test-${title}` : `test-${string}`
|
||||
>title : string
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,14 @@ function ft14(t: `foo${number}`) {
|
||||
let x6: { length: number } = t;
|
||||
}
|
||||
|
||||
declare function g1<T>(x: T): T;
|
||||
declare function g2<T extends string>(x: T): T;
|
||||
|
||||
function ft20(s: string) {
|
||||
let x1 = g1(`xyz-${s}`); // string
|
||||
let x2 = g2(`xyz-${s}`); // `xyz-${string}`
|
||||
}
|
||||
|
||||
// Repro from #41631
|
||||
|
||||
declare function takesLiteral<T extends string>(literal: T): T extends `foo.bar.${infer R}` ? R : unknown;
|
||||
@@ -99,3 +107,9 @@ type PixelValueType = `${number}px`;
|
||||
const pixelString: PixelValueType = `22px`;
|
||||
|
||||
const pixelStringWithTemplate: PixelValueType = `${pixelValue}px`;
|
||||
|
||||
// Repro from #43143
|
||||
|
||||
function getCardTitle(title: string): `test-${string}` {
|
||||
return `test-${title}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user