@@ -6639,13 +6639,23 @@ namespace ts {
6639
6639
getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
6640
6640
}
6641
6641
6642
- function includeMixinType(type: Type, types: ReadonlyArray<Type>, index: number): Type {
6642
+ function findMixins(types: ReadonlyArray<Type>): ReadonlyArray<boolean> {
6643
+ const constructorTypeCount = countWhere(types, (t) => getSignaturesOfType(t, SignatureKind.Construct).length > 0);
6644
+ const mixinFlags = map(types, isMixinConstructorType);
6645
+ if (constructorTypeCount > 0 && constructorTypeCount === countWhere(mixinFlags, (b) => b)) {
6646
+ const firstMixinIndex = mixinFlags.indexOf(/*searchElement*/ true);
6647
+ mixinFlags[firstMixinIndex] = false;
6648
+ }
6649
+ return mixinFlags;
6650
+ }
6651
+
6652
+ function includeMixinType(type: Type, types: ReadonlyArray<Type>, mixinFlags: ReadonlyArray<boolean>, index: number): Type {
6643
6653
const mixedTypes: Type[] = [];
6644
6654
for (let i = 0; i < types.length; i++) {
6645
6655
if (i === index) {
6646
6656
mixedTypes.push(type);
6647
6657
}
6648
- else if (isMixinConstructorType(types [i]) ) {
6658
+ else if (mixinFlags [i]) {
6649
6659
mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], SignatureKind.Construct)[0]));
6650
6660
}
6651
6661
}
@@ -6660,20 +6670,21 @@ namespace ts {
6660
6670
let stringIndexInfo: IndexInfo | undefined;
6661
6671
let numberIndexInfo: IndexInfo | undefined;
6662
6672
const types = type.types;
6663
- const mixinCount = countWhere(types, isMixinConstructorType);
6673
+ const mixinFlags = findMixins(types);
6674
+ const mixinCount = countWhere(mixinFlags, (b) => b);
6664
6675
for (let i = 0; i < types.length; i++) {
6665
6676
const t = type.types[i];
6666
6677
// When an intersection type contains mixin constructor types, the construct signatures from
6667
6678
// those types are discarded and their return types are mixed into the return types of all
6668
6679
// other construct signatures in the intersection type. For example, the intersection type
6669
6680
// '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature
6670
6681
// 'new(s: string) => A & B'.
6671
- if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(t) ) {
6682
+ if (!mixinFlags[i] ) {
6672
6683
let signatures = getSignaturesOfType(t, SignatureKind.Construct);
6673
6684
if (signatures.length && mixinCount > 0) {
6674
6685
signatures = map(signatures, s => {
6675
6686
const clone = cloneSignature(s);
6676
- clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, i);
6687
+ clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, mixinFlags, i);
6677
6688
return clone;
6678
6689
});
6679
6690
}
@@ -20169,12 +20180,11 @@ namespace ts {
20169
20180
const firstBase = baseTypes[0];
20170
20181
if (firstBase.flags & TypeFlags.Intersection) {
20171
20182
const types = (firstBase as IntersectionType).types;
20172
- const mixinCount = countWhere (types, isMixinConstructorType );
20183
+ const mixinFlags = findMixins (types);
20173
20184
let i = 0;
20174
20185
for (const intersectionMember of (firstBase as IntersectionType).types) {
20175
- i++;
20176
20186
// We want to ignore mixin ctors
20177
- if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(intersectionMember) ) {
20187
+ if (!mixinFlags[i] ) {
20178
20188
if (getObjectFlags(intersectionMember) & (ObjectFlags.Class | ObjectFlags.Interface)) {
20179
20189
if (intersectionMember.symbol === target) {
20180
20190
return true;
@@ -20184,6 +20194,7 @@ namespace ts {
20184
20194
}
20185
20195
}
20186
20196
}
20197
+ i++;
20187
20198
}
20188
20199
return false;
20189
20200
}
0 commit comments