Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: type ConstructorParameters does not accept generic

Using typescript 3.7, I have an interface with a property that is meant to accept a constructor function:

interface IConstruct<T> {
  type: new (...args:ConstructorParameters<T>) => T;
}

My thought is that IConstruct<User> will have a property {type: User}.
But the compiler tells me that T cannot be used there. Why is that?

TS2344: Type T does not satisfy the constraint 'new (...args: any) => any'

like image 555
BeetleJuice Avatar asked Jan 29 '26 10:01

BeetleJuice


1 Answers

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

like image 143
ford04 Avatar answered Jan 31 '26 03:01

ford04