mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-11 19:27:35 -06:00
Remove string literals from unions with matching template literals (#41276)
* Remove string literals from unions with matching template literals * Add tests * Accept new baselines
This commit is contained in:
parent
71cd5d522d
commit
40b81224f9
@ -13108,6 +13108,20 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function removeStringLiteralsMatchedByTemplateLiterals(types: Type[]) {
|
||||
const templates = filter(types, isPatternLiteralType);
|
||||
if (templates.length) {
|
||||
let i = types.length;
|
||||
while (i > 0) {
|
||||
i--;
|
||||
const t = types[i];
|
||||
if (t.flags & TypeFlags.StringLiteral && some(templates, template => isTypeSubtypeOf(t, template))) {
|
||||
orderedRemoveItemAt(types, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We sort and deduplicate the constituent types based on object identity. If the subtypeReduction
|
||||
// flag is specified we also reduce the constituent type set to only include types that aren't subtypes
|
||||
// of other types. Subtype reduction is expensive for large union types and is possible only when union
|
||||
@ -13133,6 +13147,9 @@ namespace ts {
|
||||
if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol)) {
|
||||
removeRedundantLiteralTypes(typeSet, includes);
|
||||
}
|
||||
if (includes & TypeFlags.StringLiteral && includes & TypeFlags.TemplateLiteral) {
|
||||
removeStringLiteralsMatchedByTemplateLiterals(typeSet);
|
||||
}
|
||||
break;
|
||||
case UnionReduction.Subtype:
|
||||
if (!removeSubtypes(typeSet, !(includes & TypeFlags.IncludesStructuredOrInstantiable))) {
|
||||
|
||||
@ -338,4 +338,13 @@ tests/cases/conformance/types/literal/templateLiteralTypesPatterns.ts(160,7): er
|
||||
|
||||
var aa: '0';
|
||||
var aa: '0' & `${number}`;
|
||||
|
||||
// Remove string literals from unions with matching template literals
|
||||
|
||||
let t1: `foo${string}` | 'foo1' | '1foo'; // `foo${string}` | '1foo'
|
||||
let t2: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo'; // `foo${string}` | '1foo' | 'xfoo'
|
||||
let t3: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo' | `${number}foo`; // `foo${string}` | xfoo' | `${number}foo`
|
||||
|
||||
var bb: `${number}`;
|
||||
var bb: `${number}` | '0';
|
||||
|
||||
@ -165,6 +165,15 @@ const exampleGood: B = "1 2"; // ok
|
||||
|
||||
var aa: '0';
|
||||
var aa: '0' & `${number}`;
|
||||
|
||||
// Remove string literals from unions with matching template literals
|
||||
|
||||
let t1: `foo${string}` | 'foo1' | '1foo'; // `foo${string}` | '1foo'
|
||||
let t2: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo'; // `foo${string}` | '1foo' | 'xfoo'
|
||||
let t3: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo' | `${number}foo`; // `foo${string}` | xfoo' | `${number}foo`
|
||||
|
||||
var bb: `${number}`;
|
||||
var bb: `${number}` | '0';
|
||||
|
||||
|
||||
//// [templateLiteralTypesPatterns.js]
|
||||
@ -289,3 +298,9 @@ var exampleGood = "1 2"; // ok
|
||||
// Repro from #41161
|
||||
var aa;
|
||||
var aa;
|
||||
// Remove string literals from unions with matching template literals
|
||||
var t1; // `foo${string}` | '1foo'
|
||||
var t2; // `foo${string}` | '1foo' | 'xfoo'
|
||||
var t3; // `foo${string}` | xfoo' | `${number}foo`
|
||||
var bb;
|
||||
var bb;
|
||||
|
||||
@ -401,3 +401,20 @@ var aa: '0';
|
||||
var aa: '0' & `${number}`;
|
||||
>aa : Symbol(aa, Decl(templateLiteralTypesPatterns.ts, 164, 3), Decl(templateLiteralTypesPatterns.ts, 165, 3))
|
||||
|
||||
// Remove string literals from unions with matching template literals
|
||||
|
||||
let t1: `foo${string}` | 'foo1' | '1foo'; // `foo${string}` | '1foo'
|
||||
>t1 : Symbol(t1, Decl(templateLiteralTypesPatterns.ts, 169, 3))
|
||||
|
||||
let t2: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo'; // `foo${string}` | '1foo' | 'xfoo'
|
||||
>t2 : Symbol(t2, Decl(templateLiteralTypesPatterns.ts, 170, 3))
|
||||
|
||||
let t3: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo' | `${number}foo`; // `foo${string}` | xfoo' | `${number}foo`
|
||||
>t3 : Symbol(t3, Decl(templateLiteralTypesPatterns.ts, 171, 3))
|
||||
|
||||
var bb: `${number}`;
|
||||
>bb : Symbol(bb, Decl(templateLiteralTypesPatterns.ts, 173, 3), Decl(templateLiteralTypesPatterns.ts, 174, 3))
|
||||
|
||||
var bb: `${number}` | '0';
|
||||
>bb : Symbol(bb, Decl(templateLiteralTypesPatterns.ts, 173, 3), Decl(templateLiteralTypesPatterns.ts, 174, 3))
|
||||
|
||||
|
||||
@ -560,3 +560,20 @@ var aa: '0';
|
||||
var aa: '0' & `${number}`;
|
||||
>aa : "0"
|
||||
|
||||
// Remove string literals from unions with matching template literals
|
||||
|
||||
let t1: `foo${string}` | 'foo1' | '1foo'; // `foo${string}` | '1foo'
|
||||
>t1 : `foo${string}` | "1foo"
|
||||
|
||||
let t2: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo'; // `foo${string}` | '1foo' | 'xfoo'
|
||||
>t2 : `foo${string}` | "1foo" | "xfoo"
|
||||
|
||||
let t3: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo' | `${number}foo`; // `foo${string}` | xfoo' | `${number}foo`
|
||||
>t3 : `foo${string}` | "xfoo" | `${number}foo`
|
||||
|
||||
var bb: `${number}`;
|
||||
>bb : `${number}`
|
||||
|
||||
var bb: `${number}` | '0';
|
||||
>bb : `${number}`
|
||||
|
||||
|
||||
@ -165,3 +165,12 @@ const exampleGood: B = "1 2"; // ok
|
||||
|
||||
var aa: '0';
|
||||
var aa: '0' & `${number}`;
|
||||
|
||||
// Remove string literals from unions with matching template literals
|
||||
|
||||
let t1: `foo${string}` | 'foo1' | '1foo'; // `foo${string}` | '1foo'
|
||||
let t2: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo'; // `foo${string}` | '1foo' | 'xfoo'
|
||||
let t3: `foo1` | '1foo' | 'foofoo' | `foo${string}` | 'foox' | 'xfoo' | `${number}foo`; // `foo${string}` | xfoo' | `${number}foo`
|
||||
|
||||
var bb: `${number}`;
|
||||
var bb: `${number}` | '0';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user