如何解决如何在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()
类型的代码示例?
解决方法
检查它是否适合您
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() {
// ...
}
}
,
打字稿中没有特定类方法的类型(其他语言以及TBH都从未听说过这种类型), 您可以为函数签名指定类型。
编辑: 似乎有一些我不知道的技巧 ,如其他答案所示。 但是,如果您对快速简单但有限的解决方案感兴趣:
例如:
let myAdd: (baseValue: number,increment: number) => number = (baseValue,increment) => baseValue + increment
此处提供类型的功能的更多信息: https://www.typescriptlang.org/docs/handbook/functions.html
如果足够的话,可以在装饰器的声明中使用键入的签名,如下所示:
Interface ObjectInterface {
ChildMethods: {(param) => void} [],//or whatever fuction signature meets your need,this is just an example.
ParentMethods: {(param) => void}[]
}
//this is the decorator declaration
function Hooks(obj: ObjectInterface) {
return function (
target,propertyKey: string,descriptor: PropertyDescriptor
) {
// what ever implementation you have in hooks...
};
}
这样,将非(param) => void
类型的函数传递给装饰器时,会导致编译错误。
更多信息在这里: https://www.typescriptlang.org/docs/handbook/decorators.html
这里是像我在ObjectInterface
上所做的类型化函数数组:
A Typed array of functions
我找到了解决方法
2020-10-09 17:59:49.446 21872-21872/com.gradient.tiptime E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.gradient.tiptime,PID: 21872
java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at com.gradient.tiptime.MainActivity.calculateTip(MainActivity.kt:25)
at com.gradient.tiptime.MainActivity$onCreate$1.onClick(MainActivity.kt:19)
at android.view.View.performClick(View.java:7192)
at android.view.View.performClickInternal(View.java:7166)
at android.view.View.access$3500(View.java:824)
at android.view.View$PerformClick.run(View.java:27592)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。