@@ -17533,13 +17533,11 @@ namespace ts {
17533
17533
if (containsType(targetTypes, source)) {
17534
17534
return Ternary.True;
17535
17535
}
17536
- if (targetTypes.length >= 4) {
17537
- const match = getMatchingUnionConstituentForType(<UnionType>target, source);
17538
- if (match) {
17539
- const related = isRelatedTo(source, match, /*reportErrors*/ false);
17540
- if (related) {
17541
- return related;
17542
- }
17536
+ const match = getMatchingUnionConstituentForType(<UnionType>target, source);
17537
+ if (match) {
17538
+ const related = isRelatedTo(source, match, /*reportErrors*/ false);
17539
+ if (related) {
17540
+ return related;
17543
17541
}
17544
17542
}
17545
17543
}
@@ -21378,21 +21376,32 @@ namespace ts {
21378
21376
return result;
21379
21377
}
21380
21378
21381
- function getUnitTypeProperties(unionType: UnionType): Symbol[] {
21382
- return unionType.unitTypeProperties || (unionType.unitTypeProperties =
21383
- filter(getPropertiesOfUnionOrIntersectionType(unionType), prop => !!(
21384
- getCheckFlags(prop) & CheckFlags.SyntheticProperty &&
21385
- ((<TransientSymbol>prop).checkFlags & CheckFlags.UnitDiscriminant) === CheckFlags.UnitDiscriminant)));
21379
+ function getKeyPropertyNames(unionType: UnionType): __String[] | undefined {
21380
+ const types = unionType.types;
21381
+ if (types.length < 10 || getObjectFlags(unionType) & ObjectFlags.PrimitiveUnion) {
21382
+ return undefined;
21383
+ }
21384
+ let keyPropertyNames = unionType.keyPropertyNames;
21385
+ if (!keyPropertyNames) {
21386
+ keyPropertyNames = unionType.keyPropertyNames = [];
21387
+ const propType = find(types, t => !!(t.flags & (TypeFlags.Object | TypeFlags.Intersection)) && getPropertiesOfType(t).length !== 0) || unknownType;
21388
+ for (const name of map(getPropertiesOfType(propType), prop => prop.escapedName)) {
21389
+ if (every(types, t => !(t.flags & (TypeFlags.Object | TypeFlags.Intersection)) || isUnitType(getTypeOfPropertyOfType(t, name) || unknownType))) {
21390
+ keyPropertyNames.push(name);
21391
+ }
21392
+ }
21393
+ }
21394
+ return keyPropertyNames.length ? keyPropertyNames : undefined;
21386
21395
}
21387
21396
21388
21397
function getUnionConstituentKeyForType(unionType: UnionType, type: Type) {
21389
- const unitTypeProperties = getUnitTypeProperties (unionType);
21390
- if (unitTypeProperties.length === 0 ) {
21398
+ const keyPropertyNames = getKeyPropertyNames (unionType);
21399
+ if (!keyPropertyNames ) {
21391
21400
return undefined;
21392
21401
}
21393
21402
const propTypes = [];
21394
- for (const prop of unitTypeProperties ) {
21395
- const propType = getTypeOfPropertyOfType(type, prop.escapedName );
21403
+ for (const name of keyPropertyNames ) {
21404
+ const propType = getTypeOfPropertyOfType(type, name );
21396
21405
if (!(propType && isUnitType(propType))) {
21397
21406
return undefined;
21398
21407
}
@@ -21402,14 +21411,14 @@ namespace ts {
21402
21411
}
21403
21412
21404
21413
function getUnionConstituentKeyForObjectLiteral(unionType: UnionType, node: ObjectLiteralExpression) {
21405
- const unitTypeProperties = getUnitTypeProperties (unionType);
21406
- if (unitTypeProperties.length === 0 ) {
21414
+ const keyPropertyNames = getKeyPropertyNames (unionType);
21415
+ if (!keyPropertyNames ) {
21407
21416
return undefined;
21408
21417
}
21409
21418
const propTypes = [];
21410
- for (const prop of unitTypeProperties ) {
21419
+ for (const name of keyPropertyNames ) {
21411
21420
const propNode = find(node.properties, p => p.symbol && p.kind === SyntaxKind.PropertyAssignment &&
21412
- p.symbol.escapedName === prop.escapedName && isPossiblyDiscriminantValue(p.initializer));
21421
+ p.symbol.escapedName === name && isPossiblyDiscriminantValue(p.initializer));
21413
21422
const propType = propNode && getTypeOfExpression((<PropertyAssignment>propNode).initializer);
21414
21423
if (!(propType && isUnitType(propType))) {
21415
21424
return undefined;
@@ -24717,16 +24726,10 @@ namespace ts {
24717
24726
getContextualType(node, contextFlags);
24718
24727
const instantiatedType = instantiateContextualType(contextualType, node, contextFlags);
24719
24728
if (instantiatedType && !(contextFlags && contextFlags & ContextFlags.NoConstraints && instantiatedType.flags & TypeFlags.TypeVariable)) {
24720
- const apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true);
24721
- if (apparentType.flags & TypeFlags.Union) {
24722
- if (isObjectLiteralExpression(node)) {
24723
- return discriminateContextualTypeByObjectMembers(node, apparentType as UnionType);
24724
- }
24725
- else if (isJsxAttributes(node)) {
24726
- return discriminateContextualTypeByJSXAttributes(node, apparentType as UnionType);
24727
- }
24728
- }
24729
- return apparentType;
24729
+ const discriminatedType = instantiatedType.flags & TypeFlags.Union && isObjectLiteralExpression(node) ? discriminateContextualTypeByObjectMembers(node, instantiatedType as UnionType) :
24730
+ instantiatedType.flags & TypeFlags.Union && isJsxAttributes(node) ? discriminateContextualTypeByJSXAttributes(node, instantiatedType as UnionType) :
24731
+ instantiatedType;
24732
+ return mapType(discriminatedType, getApparentType, /*noReductions*/ true);
24730
24733
}
24731
24734
}
24732
24735
0 commit comments