The problem is that Function is a very wide type and includes any function, including ones which cannot be called via new. Therefore the compiler is complaining that Function is not constuctible. The solution is therefore to use a type which is known to have a construct signature. In TypeScript, such a signature is represented by prepending the keyword new to a function signature:
type NewableFunctionSyntax = new () => object;
type NewableMethodSyntax = { new(): object };
Those types both represent a constructor that accepts no arguments and produces an instance of type assignable object. Note that while those syntaxes are different, they are essentially the same. (To see this, note that the compiler allows you to declare a var multiple times but will complain if you annotate it with different types. The fact that the following compiles with no error,
var someCtor: NewableFunctionSyntax;
var someCtor: NewableMethodSyntax; // no error
is an indication that the compiler treats NewableFunctionSyntax and NewableMethodSyntax as essentially interchangeable.)
By changing Function to one of these, your code now compiles with no errors:
function applyMixins(derivedCtor: { new(): object }, constructors: { new(): object }[]) {
//Copies methods
constructors.forEach((baseCtor) => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
Object.create(null)
);
});
});
//Copies properties
constructors.forEach((baseCtor) => {
let empty = new baseCtor();
Object.keys(empty).forEach((name) => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(empty, name) ||
Object.create(null)
);
});
});
}
Let's test out calling applyMixins() to make sure we understand what {new(): object} does and does not match:
class Works {
x = 1;
constructor() { }
}
applyMixins(Works, []); // okay
Works is fine because it is a class constructor which takes no parameters.
class CtorRequiresArg {
y: string;
constructor(y: string) { this.y = y; }
}
applyMixins(CtorRequiresArg, []); // error!
// -------> ~~~~~~~~~~~~~~~
// Type 'new (y: string) => CtorRequiresArg'
// is not assignable to type 'new () => object'
CtorRequiresArg fails because you have to pass a string argument when you construct it, like new CtorRequiresArg("hello")... but applyMixins() only accepts constructors that can be called without any arguments.
And finally:
function NotACtor() { }
applyMixins(NotACtor, []); // error!
// -------> ~~~~~~~~
// Type '() => void' provides no match
// for the signature 'new (): object'
NotACtor fails because it is not considered constructible. This may be surprising because at runtime nothing will stop you from calling new NotACtor(), but it is the compiler's opinion that if you wanted a class constructor you would be using class notation in .ts files... even when targeting an ES5 runtime, since TypeScript will down-level it for you automatically. (See microsoft/TypeScript#2310 for more information)
Playground link to code
Functionisn't known to be constructable, while, say,new () => objector{new(): object}is. Does this work for your use case? If so I'll write up an answer when I get a chance. If not, please elaborate in the question text with relevant examples. Good luck!declare type ctorType = new() => object;in the module, and then usectorTypeinstead ofFunction. But what is the difference in comparison with{new(): object}?