Consistently check assignability to template literal placeholders (#56598)

This commit is contained in:
Anders Hejlsberg 2023-11-29 14:51:39 -08:00 committed by GitHub
parent e5513254a3
commit 68b9b07264
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 4 deletions

View File

@ -25017,12 +25017,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function isValidTypeForTemplateLiteralPlaceholder(source: Type, target: Type): boolean {
if (source === target || target.flags & (TypeFlags.Any | TypeFlags.String)) {
return true;
}
if (target.flags & TypeFlags.Intersection) {
return every((target as IntersectionType).types, t => t === emptyTypeLiteralType || isValidTypeForTemplateLiteralPlaceholder(source, t));
}
if (target.flags & TypeFlags.String || isTypeAssignableTo(source, target)) {
return true;
}
if (source.flags & TypeFlags.StringLiteral) {
const value = (source as StringLiteralType).value;
return !!(target.flags & TypeFlags.Number && isValidNumberString(value, /*roundTripOnly*/ false) ||
@ -25035,7 +25035,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const texts = (source as TemplateLiteralType).texts;
return texts.length === 2 && texts[0] === "" && texts[1] === "" && isTypeAssignableTo((source as TemplateLiteralType).types[0], target);
}
return isTypeAssignableTo(source, target);
return false;
}
function inferTypesFromTemplateLiteralType(source: Type, target: TemplateLiteralType): Type[] | undefined {

View File

@ -221,4 +221,12 @@ templateLiteralTypes3.ts(141,9): error TS2367: This comparison appears to be uni
// Repro from #52685
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
// Repro from #56582
function a<T extends {id: string}>() {
let x: keyof T & string | `-${keyof T & string}`;
x = "id";
x = "-id";
}

View File

@ -195,6 +195,14 @@ function ft1<T extends string>(t: T, u: Uppercase<T>, u1: Uppercase<`1.${T}.3`>,
// Repro from #52685
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
// Repro from #56582
function a<T extends {id: string}>() {
let x: keyof T & string | `-${keyof T & string}`;
x = "id";
x = "-id";
}
//// [templateLiteralTypes3.js]
@ -291,6 +299,12 @@ function ft1(t, u, u1, u2) {
spread("1.".concat(u, ".3"), "1.".concat(u, ".4"));
spread(u1, u2);
}
// Repro from #56582
function a() {
var x;
x = "id";
x = "-id";
}
//// [templateLiteralTypes3.d.ts]
@ -363,3 +377,6 @@ declare function noSpread<P extends DotString>(args: P[]): P;
declare function spread<P extends DotString>(...args: P[]): P;
declare function ft1<T extends string>(t: T, u: Uppercase<T>, u1: Uppercase<`1.${T}.3`>, u2: Uppercase<`1.${T}.4`>): void;
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
declare function a<T extends {
id: string;
}>(): void;

View File

@ -588,3 +588,22 @@ type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
>Boom : Symbol(Boom, Decl(templateLiteralTypes3.ts, 189, 1))
>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --))
// Repro from #56582
function a<T extends {id: string}>() {
>a : Symbol(a, Decl(templateLiteralTypes3.ts, 193, 61))
>T : Symbol(T, Decl(templateLiteralTypes3.ts, 197, 11))
>id : Symbol(id, Decl(templateLiteralTypes3.ts, 197, 22))
let x: keyof T & string | `-${keyof T & string}`;
>x : Symbol(x, Decl(templateLiteralTypes3.ts, 198, 7))
>T : Symbol(T, Decl(templateLiteralTypes3.ts, 197, 11))
>T : Symbol(T, Decl(templateLiteralTypes3.ts, 197, 11))
x = "id";
>x : Symbol(x, Decl(templateLiteralTypes3.ts, 198, 7))
x = "-id";
>x : Symbol(x, Decl(templateLiteralTypes3.ts, 198, 7))
}

View File

@ -601,3 +601,23 @@ function ft1<T extends string>(t: T, u: Uppercase<T>, u1: Uppercase<`1.${T}.3`>,
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
>Boom : `a${string}` | Lowercase<string> | "def"
// Repro from #56582
function a<T extends {id: string}>() {
>a : <T extends { id: string; }>() => void
>id : string
let x: keyof T & string | `-${keyof T & string}`;
>x : (keyof T & string) | `-${keyof T & string}`
x = "id";
>x = "id" : "id"
>x : (keyof T & string) | `-${keyof T & string}`
>"id" : "id"
x = "-id";
>x = "-id" : "-id"
>x : (keyof T & string) | `-${keyof T & string}`
>"-id" : "-id"
}

View File

@ -195,3 +195,11 @@ function ft1<T extends string>(t: T, u: Uppercase<T>, u1: Uppercase<`1.${T}.3`>,
// Repro from #52685
type Boom = 'abc' | 'def' | `a${string}` | Lowercase<string>;
// Repro from #56582
function a<T extends {id: string}>() {
let x: keyof T & string | `-${keyof T & string}`;
x = "id";
x = "-id";
}