@@ -7026,13 +7026,23 @@ namespace ts {
7026
7026
getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
7027
7027
}
7028
7028
7029
- function includeMixinType(type: Type, types: ReadonlyArray<Type>, index: number): Type {
7029
+ function findMixins(types: ReadonlyArray<Type>): ReadonlyArray<boolean> {
7030
+ const constructorTypeCount = countWhere(types, (t) => getSignaturesOfType(t, SignatureKind.Construct).length > 0);
7031
+ const mixinFlags = map(types, isMixinConstructorType);
7032
+ if (constructorTypeCount > 0 && constructorTypeCount === countWhere(mixinFlags, (b) => b)) {
7033
+ const firstMixinIndex = mixinFlags.indexOf(/*searchElement*/ true);
7034
+ mixinFlags[firstMixinIndex] = false;
7035
+ }
7036
+ return mixinFlags;
7037
+ }
7038
+
7039
+ function includeMixinType(type: Type, types: ReadonlyArray<Type>, mixinFlags: ReadonlyArray<boolean>, index: number): Type {
7030
7040
const mixedTypes: Type[] = [];
7031
7041
for (let i = 0; i < types.length; i++) {
7032
7042
if (i === index) {
7033
7043
mixedTypes.push(type);
7034
7044
}
7035
- else if (isMixinConstructorType(types [i]) ) {
7045
+ else if (mixinFlags [i]) {
7036
7046
mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], SignatureKind.Construct)[0]));
7037
7047
}
7038
7048
}
@@ -7047,20 +7057,21 @@ namespace ts {
7047
7057
let stringIndexInfo: IndexInfo | undefined;
7048
7058
let numberIndexInfo: IndexInfo | undefined;
7049
7059
const types = type.types;
7050
- const mixinCount = countWhere(types, isMixinConstructorType);
7060
+ const mixinFlags = findMixins(types);
7061
+ const mixinCount = countWhere(mixinFlags, (b) => b);
7051
7062
for (let i = 0; i < types.length; i++) {
7052
7063
const t = type.types[i];
7053
7064
// When an intersection type contains mixin constructor types, the construct signatures from
7054
7065
// those types are discarded and their return types are mixed into the return types of all
7055
7066
// other construct signatures in the intersection type. For example, the intersection type
7056
7067
// '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature
7057
7068
// 'new(s: string) => A & B'.
7058
- if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(t) ) {
7069
+ if (!mixinFlags[i] ) {
7059
7070
let signatures = getSignaturesOfType(t, SignatureKind.Construct);
7060
7071
if (signatures.length && mixinCount > 0) {
7061
7072
signatures = map(signatures, s => {
7062
7073
const clone = cloneSignature(s);
7063
- clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, i);
7074
+ clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, mixinFlags, i);
7064
7075
return clone;
7065
7076
});
7066
7077
}
@@ -21104,12 +21115,11 @@ namespace ts {
21104
21115
const firstBase = baseTypes[0];
21105
21116
if (firstBase.flags & TypeFlags.Intersection) {
21106
21117
const types = (firstBase as IntersectionType).types;
21107
- const mixinCount = countWhere (types, isMixinConstructorType );
21118
+ const mixinFlags = findMixins (types);
21108
21119
let i = 0;
21109
21120
for (const intersectionMember of (firstBase as IntersectionType).types) {
21110
- i++;
21111
21121
// We want to ignore mixin ctors
21112
- if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(intersectionMember) ) {
21122
+ if (!mixinFlags[i] ) {
21113
21123
if (getObjectFlags(intersectionMember) & (ObjectFlags.Class | ObjectFlags.Interface)) {
21114
21124
if (intersectionMember.symbol === target) {
21115
21125
return true;
@@ -21119,6 +21129,7 @@ namespace ts {
21119
21129
}
21120
21130
}
21121
21131
}
21132
+ i++;
21122
21133
}
21123
21134
return false;
21124
21135
}
0 commit comments