TypeScript shows this error when you try to call `new this()` while `this` still refers to the current instance. Move the factory into a static method or cast the constructor side so that `this` has a construct signature.
The compiler complains "The type 'this' is not a constructor function type" because it resolved the expression inside `new` to the instance type (the `this` type) instead of the constructor type. Instance members only see the instance side of the class; they don't expose constructor signatures and therefore cannot be invoked with `new`. Static methods receive the polymorphic `this` that represents the constructor itself, which is why `new this()` is allowed inside a static factory. When you try to instantiate `this` from an instance method or a helper that expects an instance type, TypeScript raises TS2507 to prevent a runtime `TypeError`, because the instance value has no construct signature. You can keep the behavior you want by either moving the factory into a static method whose `this` is the constructor or by explicitly capturing the constructor (for example via `this.constructor as typeof Base` or by passing the constructor to a helper that expects an object with `new ()`).
Static methods receive the constructor as their polymorphic this type. Moving the factory to a static method lets TypeScript know that this is compatible with new:
class Base {
static create<T extends typeof Base>(this: T) {
return new this();
}
}
class Derived extends Base {}
const derived = Derived.create(); // OK, `Derived` is returnedNow this refers to the derived constructor (the static side) so new this() is allowed and your subclasses continue to work.
When you really need to instantiate from an instance method, grab this.constructor and cast it to the class constructor that actually has a new signature:
class Base {
clone() {
const Ctor = this.constructor as typeof Base;
return new Ctor();
}
}
const clone = new Base().clone(); // OK after the castThis pattern satisfies the compiler because you're calling new on a constructor type rather than the instance type that this normally represents.
If you pass the constructor to a helper, make sure the helper expects a constructable type:
function spawn<Ctor extends new () => InstanceType<Ctor>>(Ctor: Ctor) {
return new Ctor();
}
class Widget {
spawnSibling() {
return spawn(this.constructor as new () => Widget);
}
}The helper is typed around a constructor, so TypeScript does not try to treat the instance-type this as a constructor and the error goes away.
Remember that the 'this' type inside instance members represents the current value, not its constructor, so TypeScript keeps the instance and static sides separate. The polymorphic 'this' type in static members or 'typeof' references is the safe way to keep derived constructors working with 'new this()'. For factories that need the constructor inside instance code, pass it explicitly or cast 'this.constructor' to the right constructor signature; otherwise TS2507 will keep you honest.
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript