Skip to content

Commit d90e8e7

Browse files
authored
Fix constant evaluation of template string expressions (#58500)
1 parent e51cbc8 commit d90e8e7

File tree

4 files changed

+116
-2
lines changed

4 files changed

+116
-2
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39560,11 +39560,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3956039560
texts.push(span.literal.text);
3956139561
types.push(isTypeAssignableTo(type, templateConstraintType) ? type : stringType);
3956239562
}
39563+
const evaluated = node.parent.kind !== SyntaxKind.TaggedTemplateExpression && evaluate(node).value;
39564+
if (evaluated) {
39565+
return getFreshTypeOfLiteralType(getStringLiteralType(evaluated));
39566+
}
3956339567
if (isConstContext(node) || isTemplateLiteralContext(node) || someType(getContextualType(node, /*contextFlags*/ undefined) || unknownType, isTemplateLiteralContextualType)) {
3956439568
return getTemplateLiteralType(texts, types);
3956539569
}
39566-
const evaluated = node.parent.kind !== SyntaxKind.TaggedTemplateExpression && evaluate(node).value;
39567-
return evaluated ? getFreshTypeOfLiteralType(getStringLiteralType(evaluated)) : stringType;
39570+
return stringType;
3956839571
}
3956939572

3957039573
function isTemplateLiteralContextualType(type: Type): boolean {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [tests/cases/compiler/templateLiteralConstantEvaluation.ts] ////
2+
3+
=== templateLiteralConstantEvaluation.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/58494
5+
6+
function fn<T>(arg: T): T {
7+
>fn : Symbol(fn, Decl(templateLiteralConstantEvaluation.ts, 0, 0))
8+
>T : Symbol(T, Decl(templateLiteralConstantEvaluation.ts, 2, 12))
9+
>arg : Symbol(arg, Decl(templateLiteralConstantEvaluation.ts, 2, 15))
10+
>T : Symbol(T, Decl(templateLiteralConstantEvaluation.ts, 2, 12))
11+
>T : Symbol(T, Decl(templateLiteralConstantEvaluation.ts, 2, 12))
12+
13+
return arg;
14+
>arg : Symbol(arg, Decl(templateLiteralConstantEvaluation.ts, 2, 15))
15+
}
16+
17+
const a = '1';
18+
>a : Symbol(a, Decl(templateLiteralConstantEvaluation.ts, 6, 5))
19+
20+
const b = a + ' 2';
21+
>b : Symbol(b, Decl(templateLiteralConstantEvaluation.ts, 7, 5))
22+
>a : Symbol(a, Decl(templateLiteralConstantEvaluation.ts, 6, 5))
23+
24+
const c = `${b} 3`;
25+
>c : Symbol(c, Decl(templateLiteralConstantEvaluation.ts, 8, 5))
26+
>b : Symbol(b, Decl(templateLiteralConstantEvaluation.ts, 7, 5))
27+
28+
const d = `${b} 3` as const;
29+
>d : Symbol(d, Decl(templateLiteralConstantEvaluation.ts, 9, 5))
30+
>b : Symbol(b, Decl(templateLiteralConstantEvaluation.ts, 7, 5))
31+
>const : Symbol(const)
32+
33+
fn(`${b} 3`);
34+
>fn : Symbol(fn, Decl(templateLiteralConstantEvaluation.ts, 0, 0))
35+
>b : Symbol(b, Decl(templateLiteralConstantEvaluation.ts, 7, 5))
36+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//// [tests/cases/compiler/templateLiteralConstantEvaluation.ts] ////
2+
3+
=== templateLiteralConstantEvaluation.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/58494
5+
6+
function fn<T>(arg: T): T {
7+
>fn : <T>(arg: T) => T
8+
> : ^ ^^ ^^ ^^^^^
9+
>arg : T
10+
> : ^
11+
12+
return arg;
13+
>arg : T
14+
> : ^
15+
}
16+
17+
const a = '1';
18+
>a : "1"
19+
> : ^^^
20+
>'1' : "1"
21+
> : ^^^
22+
23+
const b = a + ' 2';
24+
>b : string
25+
> : ^^^^^^
26+
>a + ' 2' : string
27+
> : ^^^^^^
28+
>a : "1"
29+
> : ^^^
30+
>' 2' : " 2"
31+
> : ^^^^
32+
33+
const c = `${b} 3`;
34+
>c : "1 2 3"
35+
> : ^^^^^^^
36+
>`${b} 3` : "1 2 3"
37+
> : ^^^^^^^
38+
>b : string
39+
> : ^^^^^^
40+
41+
const d = `${b} 3` as const;
42+
>d : "1 2 3"
43+
> : ^^^^^^^
44+
>`${b} 3` as const : "1 2 3"
45+
> : ^^^^^^^
46+
>`${b} 3` : "1 2 3"
47+
> : ^^^^^^^
48+
>b : string
49+
> : ^^^^^^
50+
51+
fn(`${b} 3`);
52+
>fn(`${b} 3`) : "1 2 3"
53+
> : ^^^^^^^
54+
>fn : <T>(arg: T) => T
55+
> : ^ ^^ ^^ ^^^^^^
56+
>`${b} 3` : "1 2 3"
57+
> : ^^^^^^^
58+
>b : string
59+
> : ^^^^^^
60+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/58494
5+
6+
function fn<T>(arg: T): T {
7+
return arg;
8+
}
9+
10+
const a = '1';
11+
const b = a + ' 2';
12+
const c = `${b} 3`;
13+
const d = `${b} 3` as const;
14+
15+
fn(`${b} 3`);

0 commit comments

Comments
 (0)