Skip to content

Commit 68b9b07

Browse files
authored
Consistently check assignability to template literal placeholders (#56598)
1 parent e551325 commit 68b9b07

File tree

6 files changed

+76
-4
lines changed

6 files changed

+76
-4
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25017,12 +25017,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2501725017
}
2501825018

2501925019
function isValidTypeForTemplateLiteralPlaceholder(source: Type, target: Type): boolean {
25020-
if (source === target || target.flags & (TypeFlags.Any | TypeFlags.String)) {
25021-
return true;
25022-
}
2502325020
if (target.flags & TypeFlags.Intersection) {
2502425021
return every((target as IntersectionType).types, t => t === emptyTypeLiteralType || isValidTypeForTemplateLiteralPlaceholder(source, t));
2502525022
}
25023+
if (target.flags & TypeFlags.String || isTypeAssignableTo(source, target)) {
25024+
return true;
25025+
}
2502625026
if (source.flags & TypeFlags.StringLiteral) {
2502725027
const value = (source as StringLiteralType).value;
2502825028
return !!(target.flags & TypeFlags.Number && isValidNumberString(value, /*roundTripOnly*/ false) ||
@@ -25035,7 +25035,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2503525035
const texts = (source as TemplateLiteralType).texts;
2503625036
return texts.length === 2 && texts[0] === "" && texts[1] === "" && isTypeAssignableTo((source as TemplateLiteralType).types[0], target);
2503725037
}
25038-
return isTypeAssignableTo(source, target);
25038+
return false;
2503925039
}
2504025040

2504125041
function inferTypesFromTemplateLiteralType(source: Type, target: TemplateLiteralType): Type[] | undefined {

tests/baselines/reference/templateLiteralTypes3.errors.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,12 @@ templateLiteralTypes3.ts(141,9): error TS2367: This comparison appears to be uni
221221
// Repro from #52685
222222

223223
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
224+
225+
// Repro from #56582
226+
227+
function a<T extends {id: string}>() {
228+
let x: keyof T & string | `-${keyof T & string}`;
229+
x = "id";
230+
x = "-id";
231+
}
224232

tests/baselines/reference/templateLiteralTypes3.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,14 @@ function ft1<T extends string>(t: T, u: Uppercase<T>, u1: Uppercase<`1.${T}.3`>,
195195
// Repro from #52685
196196

197197
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
198+
199+
// Repro from #56582
200+
201+
function a<T extends {id: string}>() {
202+
let x: keyof T & string | `-${keyof T & string}`;
203+
x = "id";
204+
x = "-id";
205+
}
198206

199207

200208
//// [templateLiteralTypes3.js]
@@ -291,6 +299,12 @@ function ft1(t, u, u1, u2) {
291299
spread("1.".concat(u, ".3"), "1.".concat(u, ".4"));
292300
spread(u1, u2);
293301
}
302+
// Repro from #56582
303+
function a() {
304+
var x;
305+
x = "id";
306+
x = "-id";
307+
}
294308

295309

296310
//// [templateLiteralTypes3.d.ts]
@@ -363,3 +377,6 @@ declare function noSpread<P extends DotString>(args: P[]): P;
363377
declare function spread<P extends DotString>(...args: P[]): P;
364378
declare function ft1<T extends string>(t: T, u: Uppercase<T>, u1: Uppercase<`1.${T}.3`>, u2: Uppercase<`1.${T}.4`>): void;
365379
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
380+
declare function a<T extends {
381+
id: string;
382+
}>(): void;

tests/baselines/reference/templateLiteralTypes3.symbols

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,22 @@ type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
588588
>Boom : Symbol(Boom, Decl(templateLiteralTypes3.ts, 189, 1))
589589
>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --))
590590

591+
// Repro from #56582
592+
593+
function a<T extends {id: string}>() {
594+
>a : Symbol(a, Decl(templateLiteralTypes3.ts, 193, 61))
595+
>T : Symbol(T, Decl(templateLiteralTypes3.ts, 197, 11))
596+
>id : Symbol(id, Decl(templateLiteralTypes3.ts, 197, 22))
597+
598+
let x: keyof T & string | `-${keyof T & string}`;
599+
>x : Symbol(x, Decl(templateLiteralTypes3.ts, 198, 7))
600+
>T : Symbol(T, Decl(templateLiteralTypes3.ts, 197, 11))
601+
>T : Symbol(T, Decl(templateLiteralTypes3.ts, 197, 11))
602+
603+
x = "id";
604+
>x : Symbol(x, Decl(templateLiteralTypes3.ts, 198, 7))
605+
606+
x = "-id";
607+
>x : Symbol(x, Decl(templateLiteralTypes3.ts, 198, 7))
608+
}
609+

tests/baselines/reference/templateLiteralTypes3.types

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,3 +601,23 @@ function ft1<T extends string>(t: T, u: Uppercase<T>, u1: Uppercase<`1.${T}.3`>,
601601
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
602602
>Boom : `a${string}` | Lowercase<string> | "def"
603603

604+
// Repro from #56582
605+
606+
function a<T extends {id: string}>() {
607+
>a : <T extends { id: string; }>() => void
608+
>id : string
609+
610+
let x: keyof T & string | `-${keyof T & string}`;
611+
>x : (keyof T & string) | `-${keyof T & string}`
612+
613+
x = "id";
614+
>x = "id" : "id"
615+
>x : (keyof T & string) | `-${keyof T & string}`
616+
>"id" : "id"
617+
618+
x = "-id";
619+
>x = "-id" : "-id"
620+
>x : (keyof T & string) | `-${keyof T & string}`
621+
>"-id" : "-id"
622+
}
623+

tests/cases/conformance/types/literal/templateLiteralTypes3.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,11 @@ function ft1<T extends string>(t: T, u: Uppercase<T>, u1: Uppercase<`1.${T}.3`>,
195195
// Repro from #52685
196196

197197
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
198+
199+
// Repro from #56582
200+
201+
function a<T extends {id: string}>() {
202+
let x: keyof T & string | `-${keyof T & string}`;
203+
x = "id";
204+
x = "-id";
205+
}

0 commit comments

Comments
 (0)