Skip to content

Commit 93acaac

Browse files
committed
Fix discriminant property check
1 parent 08022d5 commit 93acaac

File tree

2 files changed

+30
-36
lines changed

2 files changed

+30
-36
lines changed

src/compiler/checker.ts

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7669,38 +7669,37 @@ namespace ts {
76697669
return props[0];
76707670
}
76717671
let declarations: Declaration[] | undefined;
7672-
let commonType: Type | undefined;
7672+
let firstType: Type | undefined;
76737673
let nameType: Type | undefined;
76747674
const propTypes: Type[] = [];
7675-
let first = true;
7676-
let commonValueDeclaration: Declaration | undefined;
7675+
let firstValueDeclaration: Declaration | undefined;
76777676
let hasNonUniformValueDeclaration = false;
76787677
for (const prop of props) {
7679-
if (!commonValueDeclaration) {
7680-
commonValueDeclaration = prop.valueDeclaration;
7678+
if (!firstValueDeclaration) {
7679+
firstValueDeclaration = prop.valueDeclaration;
76817680
}
7682-
else if (prop.valueDeclaration !== commonValueDeclaration) {
7681+
else if (prop.valueDeclaration !== firstValueDeclaration) {
76837682
hasNonUniformValueDeclaration = true;
76847683
}
76857684
declarations = addRange(declarations, prop.declarations);
76867685
const type = getTypeOfSymbol(prop);
7687-
if (first) {
7688-
commonType = type;
7686+
if (!firstType) {
7687+
firstType = type;
76897688
nameType = prop.nameType;
7690-
first = false;
76917689
}
7692-
else {
7693-
if (type !== commonType) {
7694-
checkFlags |= CheckFlags.HasNonUniformType;
7695-
}
7690+
else if (type !== firstType) {
7691+
checkFlags |= CheckFlags.HasNonUniformType;
7692+
}
7693+
if (isLiteralType(type)) {
7694+
checkFlags |= CheckFlags.HasLiteralType;
76967695
}
76977696
propTypes.push(type);
76987697
}
76997698
addRange(propTypes, indexTypes);
77007699
const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags);
77017700
result.containingType = containingType;
7702-
if (!hasNonUniformValueDeclaration && commonValueDeclaration) {
7703-
result.valueDeclaration = commonValueDeclaration;
7701+
if (!hasNonUniformValueDeclaration && firstValueDeclaration) {
7702+
result.valueDeclaration = firstValueDeclaration;
77047703
}
77057704
result.declarations = declarations!;
77067705
result.nameType = nameType;
@@ -14814,25 +14813,18 @@ namespace ts {
1481414813
}
1481514814

1481614815
function isDiscriminantType(type: Type): boolean {
14817-
if (type.flags & TypeFlags.Union) {
14818-
if (type.flags & (TypeFlags.Boolean | TypeFlags.EnumLiteral)) {
14819-
return true;
14820-
}
14821-
let combined = 0;
14822-
for (const t of (<UnionType>type).types) combined |= t.flags;
14823-
if (combined & TypeFlags.Unit && !(combined & TypeFlags.Instantiable)) {
14824-
return true;
14825-
}
14826-
}
14827-
return false;
14816+
return !!(type.flags & TypeFlags.Union &&
14817+
(type.flags & (TypeFlags.Boolean | TypeFlags.EnumLiteral) || !isGenericIndexType(type)));
1482814818
}
1482914819

1483014820
function isDiscriminantProperty(type: Type | undefined, name: __String) {
1483114821
if (type && type.flags & TypeFlags.Union) {
1483214822
const prop = getUnionOrIntersectionProperty(<UnionType>type, name);
1483314823
if (prop && getCheckFlags(prop) & CheckFlags.SyntheticProperty) {
1483414824
if ((<TransientSymbol>prop).isDiscriminantProperty === undefined) {
14835-
(<TransientSymbol>prop).isDiscriminantProperty = !!((<TransientSymbol>prop).checkFlags & CheckFlags.HasNonUniformType) && isDiscriminantType(getTypeOfSymbol(prop));
14825+
(<TransientSymbol>prop).isDiscriminantProperty =
14826+
((<TransientSymbol>prop).checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant &&
14827+
isDiscriminantType(getTypeOfSymbol(prop));
1483614828
}
1483714829
return !!(<TransientSymbol>prop).isDiscriminantProperty;
1483814830
}

src/compiler/types.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3677,15 +3677,17 @@ namespace ts {
36773677
Readonly = 1 << 3, // Readonly transient symbol
36783678
Partial = 1 << 4, // Synthetic property present in some but not all constituents
36793679
HasNonUniformType = 1 << 5, // Synthetic property with non-uniform type in constituents
3680-
ContainsPublic = 1 << 6, // Synthetic property with public constituent(s)
3681-
ContainsProtected = 1 << 7, // Synthetic property with protected constituent(s)
3682-
ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s)
3683-
ContainsStatic = 1 << 9, // Synthetic property with static constituent(s)
3684-
Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name
3685-
ReverseMapped = 1 << 11, // Property of reverse-inferred homomorphic mapped type
3686-
OptionalParameter = 1 << 12, // Optional parameter
3687-
RestParameter = 1 << 13, // Rest parameter
3688-
Synthetic = SyntheticProperty | SyntheticMethod
3680+
HasLiteralType = 1 << 6, // Synthetic property with at least one literal type in constituents
3681+
ContainsPublic = 1 << 7, // Synthetic property with public constituent(s)
3682+
ContainsProtected = 1 << 8, // Synthetic property with protected constituent(s)
3683+
ContainsPrivate = 1 << 9, // Synthetic property with private constituent(s)
3684+
ContainsStatic = 1 << 10, // Synthetic property with static constituent(s)
3685+
Late = 1 << 11, // Late-bound symbol for a computed property with a dynamic name
3686+
ReverseMapped = 1 << 12, // Property of reverse-inferred homomorphic mapped type
3687+
OptionalParameter = 1 << 13, // Optional parameter
3688+
RestParameter = 1 << 14, // Rest parameter
3689+
Synthetic = SyntheticProperty | SyntheticMethod,
3690+
Discriminant = HasNonUniformType | HasLiteralType
36893691
}
36903692

36913693
/* @internal */

0 commit comments

Comments
 (0)