TypeScript Version: 2.1.4
Code
class Animal {
// constructor() {} // (This constructor works)
constructor(public p: string) {} // (This constructor errors)
}
class Cat extends Animal {}
declare function DecorateAnimal<T extends Animal>(original: { new(): T }): {
new(): T;
};
let DecoratedCat = DecorateAnimal(Cat);
Expected behavior:
I expect to be able to pass typeof Cat to a function that takes a new(): Cat. I _can_ do that unless Animal has a property, then I can't. I would at the least expect it to work in both cases or in neither case.
Actual behavior:
Errors out with Argument of type 'typeof Cat' is not assignable to parameter of type 'new () => Cat'.
As motivation, this came up in the context of declaring the types of a decorator function. A JS library I'm using decorates classes, returning a new class which makes changes to both the static and instance side of a class type. Something like this:
class Animal<P> {
constructor(public p: P) {}
}
class Cat extends Animal<string> {
meow() {}
}
interface StaticDecorations<T> {
originalClass: { new(): T };
}
interface InstanceDecorations<T> {
originalInstance: T;
makeTracks(): void;
}
declare function DecorateAnimal<T extends Animal<P>, P>(original: { new(): T }): {
new(): T & InstanceDecorations<T>;
prototype: { originalClass: { new(): T } }
};
let DecoratedCat = DecorateAnimal(Cat);
I think I found the issue
I had a similar error. The reason was that I didn't set default values for the properties in the constructor, hence the parameterless new(): T won't match.
To fix the original example:
class Animal {
// constructor() {} // (This constructor works)
// constructor(public p: string) {} // (This constructor errors)
constructor(public p = '') {} // (This constructor works)
}
class Cat extends Animal {}
declare function DecorateAnimal<T extends Animal>(original: { new(): T }): {
new(): T;
};
let DecoratedCat = DecorateAnimal(Cat);
Most helpful comment
I had a similar error. The reason was that I didn't set default values for the properties in the constructor, hence the parameterless
new(): Twon't match.To fix the original example: