mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix getTypeFacts for pattern template literal types (#41693)
* Normalize `${string}` to just string, fix getTypeFacts
* Add tests
* Accept new baselines
This commit is contained in:
@@ -13683,6 +13683,9 @@ namespace ts {
|
||||
return getLiteralType(text);
|
||||
}
|
||||
newTexts.push(text);
|
||||
if (every(newTexts, t => t === "") && every(newTypes, t => !!(t.flags & TypeFlags.String))) {
|
||||
return stringType;
|
||||
}
|
||||
const id = `${getTypeListId(newTypes)}|${map(newTexts, t => t.length).join(",")}|${newTexts.join("")}`;
|
||||
let type = templateLiteralTypes.get(id);
|
||||
if (!type) {
|
||||
@@ -21056,7 +21059,8 @@ namespace ts {
|
||||
return TypeFacts.None;
|
||||
}
|
||||
if (flags & TypeFlags.Instantiable) {
|
||||
return getTypeFacts(getBaseConstraintOfType(type) || unknownType);
|
||||
return !isPatternLiteralType(type) ? getTypeFacts(getBaseConstraintOfType(type) || unknownType) :
|
||||
strictNullChecks ? TypeFacts.NonEmptyStringStrictFacts : TypeFacts.NonEmptyStringFacts;
|
||||
}
|
||||
if (flags & TypeFlags.UnionOrIntersection) {
|
||||
return getTypeFactsOfTypes((<UnionOrIntersectionType>type).types);
|
||||
|
||||
@@ -347,4 +347,30 @@ tests/cases/conformance/types/literal/templateLiteralTypesPatterns.ts(160,7): er
|
||||
|
||||
var bb: `${number}`;
|
||||
var bb: `${number}` | '0';
|
||||
|
||||
// Normalize `${string}` to just string
|
||||
|
||||
type T2S<A extends string, B extends string> = `${A}${B}`;
|
||||
|
||||
type S10 = `${string}`; // string
|
||||
type S11 = `${string}${string}${string}`; // string
|
||||
type S12 = T2S<string, string>; // string
|
||||
|
||||
function ff1(x: `${string}-${string}`) {
|
||||
let s1 = x && 42; // number
|
||||
let s2 = x || 42; // `${string}-${string}`
|
||||
}
|
||||
|
||||
// Repro from #41651
|
||||
|
||||
export type Id<TA, TId extends string = string> = `${TId}-${TId}`;
|
||||
|
||||
export class AA {}
|
||||
|
||||
export abstract class BB {
|
||||
abstract get(id: Id<AA>): void;
|
||||
update(id: Id<AA>): void {
|
||||
this.get(id!);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,10 +174,38 @@ let t3: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo' | `${numbe
|
||||
|
||||
var bb: `${number}`;
|
||||
var bb: `${number}` | '0';
|
||||
|
||||
// Normalize `${string}` to just string
|
||||
|
||||
type T2S<A extends string, B extends string> = `${A}${B}`;
|
||||
|
||||
type S10 = `${string}`; // string
|
||||
type S11 = `${string}${string}${string}`; // string
|
||||
type S12 = T2S<string, string>; // string
|
||||
|
||||
function ff1(x: `${string}-${string}`) {
|
||||
let s1 = x && 42; // number
|
||||
let s2 = x || 42; // `${string}-${string}`
|
||||
}
|
||||
|
||||
// Repro from #41651
|
||||
|
||||
export type Id<TA, TId extends string = string> = `${TId}-${TId}`;
|
||||
|
||||
export class AA {}
|
||||
|
||||
export abstract class BB {
|
||||
abstract get(id: Id<AA>): void;
|
||||
update(id: Id<AA>): void {
|
||||
this.get(id!);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [templateLiteralTypesPatterns.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.BB = exports.AA = void 0;
|
||||
// ok
|
||||
var a = "/bin";
|
||||
// not ok
|
||||
@@ -304,3 +332,22 @@ var t2; // `foo${string}` | '1foo' | 'xfoo'
|
||||
var t3; // `foo${string}` | xfoo' | `${number}foo`
|
||||
var bb;
|
||||
var bb;
|
||||
function ff1(x) {
|
||||
var s1 = x && 42; // number
|
||||
var s2 = x || 42; // `${string}-${string}`
|
||||
}
|
||||
var AA = /** @class */ (function () {
|
||||
function AA() {
|
||||
}
|
||||
return AA;
|
||||
}());
|
||||
exports.AA = AA;
|
||||
var BB = /** @class */ (function () {
|
||||
function BB() {
|
||||
}
|
||||
BB.prototype.update = function (id) {
|
||||
this.get(id);
|
||||
};
|
||||
return BB;
|
||||
}());
|
||||
exports.BB = BB;
|
||||
|
||||
@@ -418,3 +418,70 @@ var bb: `${number}`;
|
||||
var bb: `${number}` | '0';
|
||||
>bb : Symbol(bb, Decl(templateLiteralTypesPatterns.ts, 173, 3), Decl(templateLiteralTypesPatterns.ts, 174, 3))
|
||||
|
||||
// Normalize `${string}` to just string
|
||||
|
||||
type T2S<A extends string, B extends string> = `${A}${B}`;
|
||||
>T2S : Symbol(T2S, Decl(templateLiteralTypesPatterns.ts, 174, 26))
|
||||
>A : Symbol(A, Decl(templateLiteralTypesPatterns.ts, 178, 9))
|
||||
>B : Symbol(B, Decl(templateLiteralTypesPatterns.ts, 178, 26))
|
||||
>A : Symbol(A, Decl(templateLiteralTypesPatterns.ts, 178, 9))
|
||||
>B : Symbol(B, Decl(templateLiteralTypesPatterns.ts, 178, 26))
|
||||
|
||||
type S10 = `${string}`; // string
|
||||
>S10 : Symbol(S10, Decl(templateLiteralTypesPatterns.ts, 178, 58))
|
||||
|
||||
type S11 = `${string}${string}${string}`; // string
|
||||
>S11 : Symbol(S11, Decl(templateLiteralTypesPatterns.ts, 180, 23))
|
||||
|
||||
type S12 = T2S<string, string>; // string
|
||||
>S12 : Symbol(S12, Decl(templateLiteralTypesPatterns.ts, 181, 41))
|
||||
>T2S : Symbol(T2S, Decl(templateLiteralTypesPatterns.ts, 174, 26))
|
||||
|
||||
function ff1(x: `${string}-${string}`) {
|
||||
>ff1 : Symbol(ff1, Decl(templateLiteralTypesPatterns.ts, 182, 31))
|
||||
>x : Symbol(x, Decl(templateLiteralTypesPatterns.ts, 184, 13))
|
||||
|
||||
let s1 = x && 42; // number
|
||||
>s1 : Symbol(s1, Decl(templateLiteralTypesPatterns.ts, 185, 7))
|
||||
>x : Symbol(x, Decl(templateLiteralTypesPatterns.ts, 184, 13))
|
||||
|
||||
let s2 = x || 42; // `${string}-${string}`
|
||||
>s2 : Symbol(s2, Decl(templateLiteralTypesPatterns.ts, 186, 7))
|
||||
>x : Symbol(x, Decl(templateLiteralTypesPatterns.ts, 184, 13))
|
||||
}
|
||||
|
||||
// Repro from #41651
|
||||
|
||||
export type Id<TA, TId extends string = string> = `${TId}-${TId}`;
|
||||
>Id : Symbol(Id, Decl(templateLiteralTypesPatterns.ts, 187, 1))
|
||||
>TA : Symbol(TA, Decl(templateLiteralTypesPatterns.ts, 191, 15))
|
||||
>TId : Symbol(TId, Decl(templateLiteralTypesPatterns.ts, 191, 18))
|
||||
>TId : Symbol(TId, Decl(templateLiteralTypesPatterns.ts, 191, 18))
|
||||
>TId : Symbol(TId, Decl(templateLiteralTypesPatterns.ts, 191, 18))
|
||||
|
||||
export class AA {}
|
||||
>AA : Symbol(AA, Decl(templateLiteralTypesPatterns.ts, 191, 66))
|
||||
|
||||
export abstract class BB {
|
||||
>BB : Symbol(BB, Decl(templateLiteralTypesPatterns.ts, 193, 18))
|
||||
|
||||
abstract get(id: Id<AA>): void;
|
||||
>get : Symbol(BB.get, Decl(templateLiteralTypesPatterns.ts, 195, 26))
|
||||
>id : Symbol(id, Decl(templateLiteralTypesPatterns.ts, 196, 17))
|
||||
>Id : Symbol(Id, Decl(templateLiteralTypesPatterns.ts, 187, 1))
|
||||
>AA : Symbol(AA, Decl(templateLiteralTypesPatterns.ts, 191, 66))
|
||||
|
||||
update(id: Id<AA>): void {
|
||||
>update : Symbol(BB.update, Decl(templateLiteralTypesPatterns.ts, 196, 35))
|
||||
>id : Symbol(id, Decl(templateLiteralTypesPatterns.ts, 197, 11))
|
||||
>Id : Symbol(Id, Decl(templateLiteralTypesPatterns.ts, 187, 1))
|
||||
>AA : Symbol(AA, Decl(templateLiteralTypesPatterns.ts, 191, 66))
|
||||
|
||||
this.get(id!);
|
||||
>this.get : Symbol(BB.get, Decl(templateLiteralTypesPatterns.ts, 195, 26))
|
||||
>this : Symbol(BB, Decl(templateLiteralTypesPatterns.ts, 193, 18))
|
||||
>get : Symbol(BB.get, Decl(templateLiteralTypesPatterns.ts, 195, 26))
|
||||
>id : Symbol(id, Decl(templateLiteralTypesPatterns.ts, 197, 11))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -577,3 +577,63 @@ var bb: `${number}`;
|
||||
var bb: `${number}` | '0';
|
||||
>bb : `${number}`
|
||||
|
||||
// Normalize `${string}` to just string
|
||||
|
||||
type T2S<A extends string, B extends string> = `${A}${B}`;
|
||||
>T2S : `${A}${B}`
|
||||
|
||||
type S10 = `${string}`; // string
|
||||
>S10 : string
|
||||
|
||||
type S11 = `${string}${string}${string}`; // string
|
||||
>S11 : string
|
||||
|
||||
type S12 = T2S<string, string>; // string
|
||||
>S12 : string
|
||||
|
||||
function ff1(x: `${string}-${string}`) {
|
||||
>ff1 : (x: `${string}-${string}`) => void
|
||||
>x : `${string}-${string}`
|
||||
|
||||
let s1 = x && 42; // number
|
||||
>s1 : number
|
||||
>x && 42 : 42
|
||||
>x : `${string}-${string}`
|
||||
>42 : 42
|
||||
|
||||
let s2 = x || 42; // `${string}-${string}`
|
||||
>s2 : `${string}-${string}`
|
||||
>x || 42 : `${string}-${string}`
|
||||
>x : `${string}-${string}`
|
||||
>42 : 42
|
||||
}
|
||||
|
||||
// Repro from #41651
|
||||
|
||||
export type Id<TA, TId extends string = string> = `${TId}-${TId}`;
|
||||
>Id : `${TId}-${TId}`
|
||||
|
||||
export class AA {}
|
||||
>AA : AA
|
||||
|
||||
export abstract class BB {
|
||||
>BB : BB
|
||||
|
||||
abstract get(id: Id<AA>): void;
|
||||
>get : (id: Id<AA>) => void
|
||||
>id : `${string}-${string}`
|
||||
|
||||
update(id: Id<AA>): void {
|
||||
>update : (id: Id<AA>) => void
|
||||
>id : `${string}-${string}`
|
||||
|
||||
this.get(id!);
|
||||
>this.get(id!) : void
|
||||
>this.get : (id: `${string}-${string}`) => void
|
||||
>this : this
|
||||
>get : (id: `${string}-${string}`) => void
|
||||
>id! : `${string}-${string}`
|
||||
>id : `${string}-${string}`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -174,3 +174,29 @@ let t3: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo' | `${numbe
|
||||
|
||||
var bb: `${number}`;
|
||||
var bb: `${number}` | '0';
|
||||
|
||||
// Normalize `${string}` to just string
|
||||
|
||||
type T2S<A extends string, B extends string> = `${A}${B}`;
|
||||
|
||||
type S10 = `${string}`; // string
|
||||
type S11 = `${string}${string}${string}`; // string
|
||||
type S12 = T2S<string, string>; // string
|
||||
|
||||
function ff1(x: `${string}-${string}`) {
|
||||
let s1 = x && 42; // number
|
||||
let s2 = x || 42; // `${string}-${string}`
|
||||
}
|
||||
|
||||
// Repro from #41651
|
||||
|
||||
export type Id<TA, TId extends string = string> = `${TId}-${TId}`;
|
||||
|
||||
export class AA {}
|
||||
|
||||
export abstract class BB {
|
||||
abstract get(id: Id<AA>): void;
|
||||
update(id: Id<AA>): void {
|
||||
this.get(id!);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user