The type of ConstructorParameters looks like this:
type ConstructorParameters<T extends new (...args: any) => any> =
T extends new (...args: infer P) => any ? P : never;
So type parameter T itself has to extend some sort of constructor function defined by the constraint extends new (...args: any) => any. Write above example like this and you should be good to go:
class User {
constructor(public name: string) { }
}
// add constructor function type constraint for T
interface IConstruct<T extends new (...args: any) => any> {
// we can use built-in InstanceType to infer instance type from class type
type: new (...args: ConstructorParameters<T>) => InstanceType<T>;
}
type UserConstruct = IConstruct<typeof User>
const constr: UserConstruct = {
type: User
}
constr.type // new (name: string) => User
const userInstance = new constr.type("John") // userInstance: User
console.log(userInstance.name) // John
Playground