Skip to content

Commit 5cc6531

Browse files
ahejlsbergJack-Works
authored andcommitted
Handle cases where 'as T' maps multiple properties onto one
1 parent 0ccbad0 commit 5cc6531

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

src/compiler/checker.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10399,24 +10399,25 @@ namespace ts {
1039910399
}
1040010400
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
1040110401

10402-
function addMemberForKeyType(t: Type) {
10403-
const mapper = appendTypeMapping(type.mapper, typeParameter, t);
10404-
const propNameType = nameType ? instantiateType(nameType, mapper) : t;
10405-
forEachType(propNameType, t => addMemberForKeyTypeWorker(t, mapper));
10402+
function addMemberForKeyType(keyType: Type) {
10403+
const mapper = appendTypeMapping(type.mapper, typeParameter, keyType);
10404+
const propNameType = nameType ? instantiateType(nameType, mapper) : keyType;
10405+
forEachType(propNameType, t => addMemberForKeyTypeWorker(keyType, t, mapper));
1040610406
}
1040710407

10408-
function addMemberForKeyTypeWorker(t: Type, mapper: TypeMapper) {
10408+
function addMemberForKeyTypeWorker(keyType: Type, propNameType: Type, mapper: TypeMapper) {
1040910409
// If the current iteration type constituent is a string literal type, create a property.
1041010410
// Otherwise, for type string create a string index signature.
10411-
if (isTypeUsableAsPropertyName(t)) {
10412-
const propName = getPropertyNameFromType(t);
10411+
if (isTypeUsableAsPropertyName(propNameType)) {
10412+
const propName = getPropertyNameFromType(propNameType);
1041310413
// String enum members from separate enums with identical values
1041410414
// are distinct types with the same property name. Make the resulting
1041510415
// property symbol's name type be the union of those enum member types.
1041610416
const existingProp = members.get(propName) as MappedSymbol | undefined;
1041710417
if (existingProp) {
10418-
existingProp.nameType = getUnionType([existingProp.nameType!, t]);
10419-
existingProp.mapper = appendTypeMapping(type.mapper, typeParameter, existingProp.nameType);
10418+
existingProp.nameType = getUnionType([existingProp.nameType!, propNameType]);
10419+
const existingKeyType = instantiateType(typeParameter, existingProp.mapper);
10420+
existingProp.mapper = appendTypeMapping(type.mapper, typeParameter, getUnionType([existingKeyType, keyType]));
1042010421
}
1042110422
else {
1042210423
const modifiersProp = getPropertyOfType(modifiersType, propName);
@@ -10432,15 +10433,16 @@ namespace ts {
1043210433
prop.syntheticOrigin = modifiersProp;
1043310434
prop.declarations = modifiersProp.declarations;
1043410435
}
10435-
prop.nameType = t;
10436+
prop.nameType = propNameType;
1043610437
prop.mapper = mapper;
1043710438
members.set(propName, prop);
1043810439
}
1043910440
}
10440-
else if (t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum)) {
10441+
else if (propNameType.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum)) {
1044110442
const propType = instantiateType(templateType, mapper);
10442-
if (t.flags & (TypeFlags.Any | TypeFlags.String)) {
10443-
stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly));
10443+
if (propNameType.flags & (TypeFlags.Any | TypeFlags.String)) {
10444+
stringIndexInfo = createIndexInfo(stringIndexInfo ? getUnionType([stringIndexInfo.type, propType]) : propType,
10445+
!!(templateModifiers & MappedTypeModifiers.IncludeReadonly));
1044410446
}
1044510447
else {
1044610448
numberIndexInfo = createIndexInfo(numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType,

0 commit comments

Comments
 (0)