Typescript 泛型类型,该泛型类型包含具有此方法参数的类的方法

Typescript 泛型类型,该泛型类型包含具有此方法参数的类的方法,typescript,typescript-typings,typescript-generics,Typescript,Typescript Typings,Typescript Generics,我想创建一个泛型类型,该类型将保存一个存在于具有此方法参数的clas上的方法,但是当我向泛型类型提供类实例时,我得到了[never,never] 我会在类中使用这种类型,所以我提供了一个潜在用法的简化示例 类内的示例用法 type AnyClass = { new (...arg0: any): any } type SingeTask<V extends InstanceType<AnyClass>> = [ Extract<keyof V, (...arg

我想创建一个泛型类型,该类型将保存一个存在于具有此方法参数的clas上的方法,但是当我向泛型类型提供类实例时,我得到了[never,never]

我会在类中使用这种类型,所以我提供了一个潜在用法的简化示例

类内的示例用法

type AnyClass = { new (...arg0: any): any }

type SingeTask<V extends InstanceType<AnyClass>> = [
  Extract<keyof V, (...arg0: any) => any>,
  Parameters<Extract<keyof V, (...arg0: any) => any>>
]

type Task<V extends InstanceType<AnyClass>> = {
  task: SingeTask<V>
  resolve: (value?: unknown) => void
  reject: (reason: any) => void
}

class Queue<T extends AnyClass> {
  instances: InstanceType<T>[] = []
  queue: Task<T>[] = []
  object: T

  constructor(object: T) {
    this.object = object
  }

  addInstance( number:number) {
      for (i; i < number; i++) {
        this.instances.push(new this.object())
  }

  

  runTasksInQueue(
    instance: InstanceType<T>,
    { task, reject, resolve }: Task<T>
  ) {
    try {
      const respone = Reflect.apply(instance, ...task)
      resolve(respone)
    } catch (error) {
      reject(error)
    } finally {
      const task = this.queue.pop()
      if (task) {
        this.runTasksInQueue(instance, task)
      } else {
        this.instances.push(instance)
      }
    }
  }

  addTaskToQueue(task: SingeTask<T>) {
    return new Promise((resolve, reject) => {
      const instance = this.instances.pop()
      if (instance) {
        this.runTasksInQueue(instance, { task, resolve, reject })
      } else {
        this.queue.push({ task, resolve, reject })
      }
    })
  }
}

虽然您的代码基本上是正确的,但首先有两个问题:

  • V扩展了InstanceType)。要按特定类型获取密钥,您需要类似于您在答案中看到的类型
    KeyOfType
    (我将只使用
    KeyOfType
    ,您可以阅读参考答案中关于其工作原理的解释)

  • 将这两个观察结果放在一起,我们得到了第一个可用的
    SingleTask

    type KeyOfType<T, U> = {[P in keyof T]-?: T[P] extends U ? P: never}[keyof T]
    type ValuesOfType<T, U> = {[P in keyof T]-?: T[P] extends U ? T[P]: never}[keyof T]
    // Alternate version of ValuesOfType
    // type ValuesOfType<T, U> = Extract<T[keyof T], U>
    
    type SingeTask<V extends AnyClass> = [
      KeyOfType<InstanceType<V>, (...arg0: any) => any>,
      Parameters<ValuesOfType<InstanceType<V>, (...arg0: any) => any>>
    ]
    
    但我们发现了一个微妙的问题,这是正确的:

    instanceQueue.addTaskToQueue([“getString”,[1]])//允许
    
    type KeyOfType<T, U> = {[P in keyof T]-?: T[P] extends U ? P: never}[keyof T]
    type ValuesOfType<T, U> = {[P in keyof T]-?: T[P] extends U ? T[P]: never}[keyof T]
    // Alternate version of ValuesOfType
    // type ValuesOfType<T, U> = Extract<T[keyof T], U>
    
    type SingeTask<V extends AnyClass> = [
      KeyOfType<InstanceType<V>, (...arg0: any) => any>,
      Parameters<ValuesOfType<InstanceType<V>, (...arg0: any) => any>>
    ]
    
    class mockClass {
      public field: string = ""
      getNumber(n: number) { return n }
      getString(s: string) { return s }
    }
    
    const instanceQueue = new Queue(mockClass)
    instanceQueue.addInstance(5)
    instanceQueue.addTaskToQueue(["getNumber", [1]]) // one number is ok ✅
    instanceQueue.addTaskToQueue(["getString", ["A"]]) // one string is ok ✅
    instanceQueue.addTaskToQueue(["getString", ["A", "B"]]) // not ok ✅
    instanceQueue.addTaskToQueue(["field", []]) // no fields ✅