首页 > 解决方案 > 如何在 TypeScript 中使装饰器类型安全?

问题描述

例子:

class Parent {
  parentMethod() {
    // ...
  }
}

@Hooks({
  // Only methods from the `Child` class (including inherited methods) must be allowed here
  childMethod: [/* ... */],
  parentMethod: [/* ... */]
})
class Child extends Parent {
  childMethod() {
    // ...
  }
}

装饰器将@Hooks()对象作为参数。在此对象中,键是类中的方法名称Child。如何使@Hooks()装饰器类型安全?您能否提供一个包含类型的代码示例@Hooks()

标签: typescripttypesdecorator

解决方案


如果它对你有用,请检查它

interface ClassType<T> extends Function {
    new (...args: any[]): T;
}

type MethodKeys<T> = ({
  [K in keyof T]: T[K] extends Function ? K : never
})[keyof T]

type HooksOptions<T> = {
  [K in MethodKeys<T>]: []
}

function Hooks<T>(_options: HooksOptions<T>) {
  return function (ctor: ClassType<T>): ClassType<T> {
    return ctor
  }
}

class Parent {
  parentMethod() {
    // ...
  }
}

@Hooks<Child>({
  childMethod: [/* ... */],
  parentMethod: [/* ... */]
})
class Child extends Parent {
  childMethod() {
    // ...
  }
}

@Hooks("invalid-value") // error
class Child2 extends Parent {
  childMethod() {
    // ...
  }
}


@Hooks<Child3>({
  c: [], // error
  childMethod: [/* ... */],
  childMethod2: [/* ... */], // error
  parentMethod: [/* ... */]
})

class Child3 extends Parent {
  public c: string = ''
  childMethod() {
    // ...
  }
}

操场


推荐阅读