mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Cache the regularized form of union types (#37749)
* Cache the regularized form of union types * Inline function because why not * Introduce two fastpasths into isRelatedTo
This commit is contained in:
parent
349ae45a2c
commit
6d25c01d09
@ -13489,7 +13489,7 @@ namespace ts {
|
||||
|
||||
function getRegularTypeOfLiteralType(type: Type): Type {
|
||||
return type.flags & TypeFlags.Literal ? (<LiteralType>type).regularType :
|
||||
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getRegularTypeOfLiteralType)) :
|
||||
type.flags & TypeFlags.Union ? ((<UnionType>type).regularType || ((<UnionType>type).regularType = getUnionType(sameMap((<UnionType>type).types, getRegularTypeOfLiteralType)) as UnionType)) :
|
||||
type;
|
||||
}
|
||||
|
||||
@ -15487,6 +15487,16 @@ namespace ts {
|
||||
return isIdenticalTo(source, target);
|
||||
}
|
||||
|
||||
|
||||
// We fastpath comparing a type parameter to exactly its constraint, as this is _super_ common,
|
||||
// and otherwise, for type parameters in large unions, causes us to need to compare the union to itself,
|
||||
// as we break down the _target_ union first, _then_ get the source constraint - so for every
|
||||
// member of the target, we attempt to find a match in the source. This avoids that in cases where
|
||||
// the target is exactly the constraint.
|
||||
if (source.flags & TypeFlags.TypeParameter && getConstraintOfType(source) === target) {
|
||||
return Ternary.True;
|
||||
}
|
||||
|
||||
// Try to see if we're relating something like `Foo` -> `Bar | null | undefined`.
|
||||
// If so, reporting the `null` and `undefined` in the type is hardly useful.
|
||||
// First, see if we're even relating an object type to a union.
|
||||
@ -15820,7 +15830,16 @@ namespace ts {
|
||||
function eachTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
|
||||
let result = Ternary.True;
|
||||
const sourceTypes = source.types;
|
||||
for (const sourceType of sourceTypes) {
|
||||
for (let i = 0; i < sourceTypes.length; i++) {
|
||||
const sourceType = sourceTypes[i];
|
||||
if (target.flags & TypeFlags.Union && (target as UnionType).types.length === sourceTypes.length) {
|
||||
// many unions are mappings of one another; in such cases, simply comparing members at the same index can shortcut the comparison
|
||||
const related = isRelatedTo(sourceType, (target as UnionType).types[i], /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
|
||||
if (related) {
|
||||
result &= related;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const related = isRelatedTo(sourceType, target, reportErrors, /*headMessage*/ undefined, intersectionState);
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
|
||||
@ -4653,6 +4653,8 @@ namespace ts {
|
||||
export interface UnionType extends UnionOrIntersectionType {
|
||||
/* @internal */
|
||||
resolvedReducedType: Type;
|
||||
/* @internal */
|
||||
regularType: UnionType;
|
||||
}
|
||||
|
||||
export interface IntersectionType extends UnionOrIntersectionType {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user