mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
fix(48034): Get a literal string of type intersection in a template literal type (#48044)
This commit is contained in:
+13
-5
@@ -15256,24 +15256,32 @@ namespace ts {
|
||||
}
|
||||
return type;
|
||||
|
||||
function addSpans(texts: readonly string[], types: readonly Type[]): boolean {
|
||||
function addSpans(texts: readonly string[] | string, types: readonly Type[]): boolean {
|
||||
const isTextsArray = isArray(texts);
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
const t = types[i];
|
||||
const addText = isTextsArray ? texts[i + 1] : texts;
|
||||
if (t.flags & (TypeFlags.Literal | TypeFlags.Null | TypeFlags.Undefined)) {
|
||||
text += getTemplateStringForType(t) || "";
|
||||
text += texts[i + 1];
|
||||
text += addText;
|
||||
if (!isTextsArray) return true;
|
||||
}
|
||||
else if (t.flags & TypeFlags.TemplateLiteral) {
|
||||
text += (t as TemplateLiteralType).texts[0];
|
||||
if (!addSpans((t as TemplateLiteralType).texts, (t as TemplateLiteralType).types)) return false;
|
||||
text += texts[i + 1];
|
||||
text += addText;
|
||||
if (!isTextsArray) return true;
|
||||
}
|
||||
else if (isGenericIndexType(t) || isPatternLiteralPlaceholderType(t)) {
|
||||
newTypes.push(t);
|
||||
newTexts.push(text);
|
||||
text = texts[i + 1];
|
||||
text = addText;
|
||||
}
|
||||
else {
|
||||
else if (t.flags & TypeFlags.Intersection) {
|
||||
const added = addSpans(texts[i + 1], (t as IntersectionType).types);
|
||||
if (!added) return false;
|
||||
}
|
||||
else if (isTextsArray) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//// [templateLiteralIntersection.ts]
|
||||
// https://github.com/microsoft/TypeScript/issues/48034
|
||||
const a = 'a'
|
||||
|
||||
type A = typeof a
|
||||
type MixA = A & {foo: string}
|
||||
|
||||
type OriginA1 = `${A}`
|
||||
type OriginA2 = `${MixA}`
|
||||
|
||||
type B = `${typeof a}`
|
||||
type MixB = B & { foo: string }
|
||||
|
||||
type OriginB1 = `${B}`
|
||||
type OriginB2 = `${MixB}`
|
||||
|
||||
type MixC = { foo: string } & A
|
||||
|
||||
type OriginC = `${MixC}`
|
||||
|
||||
type MixD<T extends string> =
|
||||
`${T & { foo: string }}`
|
||||
type OriginD = `${MixD<A & { foo: string }> & { foo: string }}`;
|
||||
|
||||
type E = `${A & {}}`;
|
||||
type MixE = E & {}
|
||||
type OriginE = `${MixE}`
|
||||
|
||||
type OriginF = `${A}foo${A}`;
|
||||
|
||||
//// [templateLiteralIntersection.js]
|
||||
// https://github.com/microsoft/TypeScript/issues/48034
|
||||
var a = 'a';
|
||||
@@ -0,0 +1,80 @@
|
||||
=== tests/cases/compiler/templateLiteralIntersection.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/48034
|
||||
const a = 'a'
|
||||
>a : Symbol(a, Decl(templateLiteralIntersection.ts, 1, 5))
|
||||
|
||||
type A = typeof a
|
||||
>A : Symbol(A, Decl(templateLiteralIntersection.ts, 1, 13))
|
||||
>a : Symbol(a, Decl(templateLiteralIntersection.ts, 1, 5))
|
||||
|
||||
type MixA = A & {foo: string}
|
||||
>MixA : Symbol(MixA, Decl(templateLiteralIntersection.ts, 3, 17))
|
||||
>A : Symbol(A, Decl(templateLiteralIntersection.ts, 1, 13))
|
||||
>foo : Symbol(foo, Decl(templateLiteralIntersection.ts, 4, 17))
|
||||
|
||||
type OriginA1 = `${A}`
|
||||
>OriginA1 : Symbol(OriginA1, Decl(templateLiteralIntersection.ts, 4, 29))
|
||||
>A : Symbol(A, Decl(templateLiteralIntersection.ts, 1, 13))
|
||||
|
||||
type OriginA2 = `${MixA}`
|
||||
>OriginA2 : Symbol(OriginA2, Decl(templateLiteralIntersection.ts, 6, 22))
|
||||
>MixA : Symbol(MixA, Decl(templateLiteralIntersection.ts, 3, 17))
|
||||
|
||||
type B = `${typeof a}`
|
||||
>B : Symbol(B, Decl(templateLiteralIntersection.ts, 7, 25))
|
||||
>a : Symbol(a, Decl(templateLiteralIntersection.ts, 1, 5))
|
||||
|
||||
type MixB = B & { foo: string }
|
||||
>MixB : Symbol(MixB, Decl(templateLiteralIntersection.ts, 9, 22))
|
||||
>B : Symbol(B, Decl(templateLiteralIntersection.ts, 7, 25))
|
||||
>foo : Symbol(foo, Decl(templateLiteralIntersection.ts, 10, 17))
|
||||
|
||||
type OriginB1 = `${B}`
|
||||
>OriginB1 : Symbol(OriginB1, Decl(templateLiteralIntersection.ts, 10, 31))
|
||||
>B : Symbol(B, Decl(templateLiteralIntersection.ts, 7, 25))
|
||||
|
||||
type OriginB2 = `${MixB}`
|
||||
>OriginB2 : Symbol(OriginB2, Decl(templateLiteralIntersection.ts, 12, 22))
|
||||
>MixB : Symbol(MixB, Decl(templateLiteralIntersection.ts, 9, 22))
|
||||
|
||||
type MixC = { foo: string } & A
|
||||
>MixC : Symbol(MixC, Decl(templateLiteralIntersection.ts, 13, 25))
|
||||
>foo : Symbol(foo, Decl(templateLiteralIntersection.ts, 15, 13))
|
||||
>A : Symbol(A, Decl(templateLiteralIntersection.ts, 1, 13))
|
||||
|
||||
type OriginC = `${MixC}`
|
||||
>OriginC : Symbol(OriginC, Decl(templateLiteralIntersection.ts, 15, 31))
|
||||
>MixC : Symbol(MixC, Decl(templateLiteralIntersection.ts, 13, 25))
|
||||
|
||||
type MixD<T extends string> =
|
||||
>MixD : Symbol(MixD, Decl(templateLiteralIntersection.ts, 17, 24))
|
||||
>T : Symbol(T, Decl(templateLiteralIntersection.ts, 19, 10))
|
||||
|
||||
`${T & { foo: string }}`
|
||||
>T : Symbol(T, Decl(templateLiteralIntersection.ts, 19, 10))
|
||||
>foo : Symbol(foo, Decl(templateLiteralIntersection.ts, 20, 12))
|
||||
|
||||
type OriginD = `${MixD<A & { foo: string }> & { foo: string }}`;
|
||||
>OriginD : Symbol(OriginD, Decl(templateLiteralIntersection.ts, 20, 28))
|
||||
>MixD : Symbol(MixD, Decl(templateLiteralIntersection.ts, 17, 24))
|
||||
>A : Symbol(A, Decl(templateLiteralIntersection.ts, 1, 13))
|
||||
>foo : Symbol(foo, Decl(templateLiteralIntersection.ts, 21, 28))
|
||||
>foo : Symbol(foo, Decl(templateLiteralIntersection.ts, 21, 47))
|
||||
|
||||
type E = `${A & {}}`;
|
||||
>E : Symbol(E, Decl(templateLiteralIntersection.ts, 21, 64))
|
||||
>A : Symbol(A, Decl(templateLiteralIntersection.ts, 1, 13))
|
||||
|
||||
type MixE = E & {}
|
||||
>MixE : Symbol(MixE, Decl(templateLiteralIntersection.ts, 23, 21))
|
||||
>E : Symbol(E, Decl(templateLiteralIntersection.ts, 21, 64))
|
||||
|
||||
type OriginE = `${MixE}`
|
||||
>OriginE : Symbol(OriginE, Decl(templateLiteralIntersection.ts, 24, 18))
|
||||
>MixE : Symbol(MixE, Decl(templateLiteralIntersection.ts, 23, 21))
|
||||
|
||||
type OriginF = `${A}foo${A}`;
|
||||
>OriginF : Symbol(OriginF, Decl(templateLiteralIntersection.ts, 25, 24))
|
||||
>A : Symbol(A, Decl(templateLiteralIntersection.ts, 1, 13))
|
||||
>A : Symbol(A, Decl(templateLiteralIntersection.ts, 1, 13))
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
=== tests/cases/compiler/templateLiteralIntersection.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/48034
|
||||
const a = 'a'
|
||||
>a : "a"
|
||||
>'a' : "a"
|
||||
|
||||
type A = typeof a
|
||||
>A : "a"
|
||||
>a : "a"
|
||||
|
||||
type MixA = A & {foo: string}
|
||||
>MixA : MixA
|
||||
>foo : string
|
||||
|
||||
type OriginA1 = `${A}`
|
||||
>OriginA1 : "a"
|
||||
|
||||
type OriginA2 = `${MixA}`
|
||||
>OriginA2 : "a"
|
||||
|
||||
type B = `${typeof a}`
|
||||
>B : "a"
|
||||
>a : "a"
|
||||
|
||||
type MixB = B & { foo: string }
|
||||
>MixB : MixB
|
||||
>foo : string
|
||||
|
||||
type OriginB1 = `${B}`
|
||||
>OriginB1 : "a"
|
||||
|
||||
type OriginB2 = `${MixB}`
|
||||
>OriginB2 : "a"
|
||||
|
||||
type MixC = { foo: string } & A
|
||||
>MixC : MixC
|
||||
>foo : string
|
||||
|
||||
type OriginC = `${MixC}`
|
||||
>OriginC : "a"
|
||||
|
||||
type MixD<T extends string> =
|
||||
>MixD : `${T & { foo: string; }}`
|
||||
|
||||
`${T & { foo: string }}`
|
||||
>foo : string
|
||||
|
||||
type OriginD = `${MixD<A & { foo: string }> & { foo: string }}`;
|
||||
>OriginD : "a"
|
||||
>foo : string
|
||||
>foo : string
|
||||
|
||||
type E = `${A & {}}`;
|
||||
>E : "a"
|
||||
|
||||
type MixE = E & {}
|
||||
>MixE : MixE
|
||||
|
||||
type OriginE = `${MixE}`
|
||||
>OriginE : "a"
|
||||
|
||||
type OriginF = `${A}foo${A}`;
|
||||
>OriginF : "afooa"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// https://github.com/microsoft/TypeScript/issues/48034
|
||||
const a = 'a'
|
||||
|
||||
type A = typeof a
|
||||
type MixA = A & {foo: string}
|
||||
|
||||
type OriginA1 = `${A}`
|
||||
type OriginA2 = `${MixA}`
|
||||
|
||||
type B = `${typeof a}`
|
||||
type MixB = B & { foo: string }
|
||||
|
||||
type OriginB1 = `${B}`
|
||||
type OriginB2 = `${MixB}`
|
||||
|
||||
type MixC = { foo: string } & A
|
||||
|
||||
type OriginC = `${MixC}`
|
||||
|
||||
type MixD<T extends string> =
|
||||
`${T & { foo: string }}`
|
||||
type OriginD = `${MixD<A & { foo: string }> & { foo: string }}`;
|
||||
|
||||
type E = `${A & {}}`;
|
||||
type MixE = E & {}
|
||||
type OriginE = `${MixE}`
|
||||
|
||||
type OriginF = `${A}foo${A}`;
|
||||
Reference in New Issue
Block a user