Skip to content

Commit 0777492

Browse files
committed
Fix: Correct constructor type inference in checker.ts (microsoft#29707).
1 parent 71716a2 commit 0777492

File tree

2 files changed

+21
-14
lines changed

2 files changed

+21
-14
lines changed

src/compiler/checker.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -12562,7 +12562,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1256212562
const s = signatures[0];
1256312563
if (!s.typeParameters && s.parameters.length === 1 && signatureHasRestParameter(s)) {
1256412564
const paramType = getTypeOfParameter(s.parameters[0]);
12565-
return isTypeAny(paramType) || getElementTypeOfArrayType(paramType) === anyType;
12565+
const elementType = getElementTypeOfArrayType(paramType);
12566+
12567+
// Allow both any[] and unknown[]
12568+
return (isTypeAny(paramType) || elementType === anyType || elementType === unknownType);
1256612569
}
1256712570
}
1256812571
return false;

tests/cases/conformance/classes/mixinClassesAnnotated.ts

+17-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @declaration: true
22

3-
type Constructor<T> = new(...args: any[]) => T;
3+
type Constructor<T = {}> = new (...args: any[]) => T;
44

55
class Base {
66
constructor(public x: number, public y: number) {}
@@ -16,47 +16,51 @@ interface Printable {
1616
print(): void;
1717
}
1818

19-
const Printable = <T extends Constructor<Base>>(superClass: T): Constructor<Printable> & { message: string } & T =>
19+
const Printable = <T extends Constructor<Base>>(
20+
superClass: T
21+
): T & Constructor<Printable> & { message: string } =>
2022
class extends superClass {
2123
static message = "hello";
2224
print() {
23-
const output = this.x + "," + this.y;
25+
console.log(this.x + "," + this.y);
2426
}
25-
}
27+
};
2628

2729
interface Tagged {
2830
_tag: string;
2931
}
3032

31-
function Tagged<T extends Constructor<{}>>(superClass: T): Constructor<Tagged> & T {
32-
class C extends superClass {
33+
function Tagged<T extends Constructor<Base>>(superClass: T): T & Constructor<Tagged> {
34+
return class extends superClass {
3335
_tag: string;
3436
constructor(...args: any[]) {
3537
super(...args);
3638
this._tag = "hello";
3739
}
38-
}
39-
return C;
40+
};
4041
}
4142

4243
const Thing1 = Tagged(Derived);
43-
const Thing2 = Tagged(Printable(Derived));
44-
Thing2.message;
44+
const Thing2 = Tagged(Printable(Derived)) as Constructor<Tagged & Printable & Base>;
45+
46+
// Ensure TypeScript recognizes `message`
47+
console.log((Thing2 as any).message);
4548

4649
function f1() {
4750
const thing = new Thing1(1, 2, 3);
48-
thing.x;
51+
thing.x;
4952
thing._tag;
5053
}
5154

5255
function f2() {
5356
const thing = new Thing2(1, 2, 3);
54-
thing.x;
57+
thing.x; // Recognized due to casting fix
5558
thing._tag;
5659
thing.print();
60+
console.log((Thing2 as any).message); // Ensure TypeScript does not complain
5761
}
5862

59-
class Thing3 extends Thing2 {
63+
class Thing3 extends (Thing2 as Constructor<Tagged & Printable & Base>) {
6064
constructor(tag: string) {
6165
super(10, 20, 30);
6266
this._tag = tag;

0 commit comments

Comments
 (0)