javascript - 具有适当签名的通用函数
问题描述
我不知道如何声明函数繁荣的第二个参数进行正确的类型检查,我的意思是如果有人将函数繁荣的第一个参数作为“foo1”发送,那么第二个参数应该只能是:(number) => void
。如果“foo2”那么(string) => void
.
interface MyFoo {
foo1: (number) => void;
foo2: (string) => void;
}
class Bar<Foo> {
public boom<T extends Foo, K extends keyof MyFoo>(first: K,
...args: Parameters<T[K] /* here I don't know how to declare this parameter */){
}
}
new Bar<MyFoo>().boom("foo1", /* callback with signature: (number) => void */)
解决方案
首先,请注意函数类型中的参数名称是必需的,因此必须更改此定义:
interface MyFoo {
foo1: (x: number) => void;
foo2: (x: string) => void;
}
现在,在方法中Bar<Foo>
我们只需要一个泛型参数,因为类型会为我们指定。我不完全理解您的用例,因为看起来您可能想要采用可变数量的参数,但这与您需要回调函数的评论不匹配。所以我假设它需要两个参数:一个键名和一个回调函数:K
boom()
Foo
boom()
boom()
class Bar<Foo> {
public boom<K extends keyof Foo>(first: K, second: Foo[K]) { }
}
然后是你如何使用它:
// okay, the callback is (x: number) => void
new Bar<MyFoo>().boom("foo1", (x: number) => console.log(x.toFixed(2)));
// error, the callback is (x: number) => void but should be (x: string) => void
new Bar<MyFoo>().boom("foo2", (x: number) => console.log(x.toFixed(2)));
顺便说一句,这不会阻止您使用具有非函数属性的接口:
interface MyFoo { age: number }
new Bar<MyFoo>().boom("age", 40); // okay
如果您要求boom()
只处理与类似函数的属性相对应的键,您将需要一些更高级的条件类型:
type KeysMatching<T, V> =
Extract<keyof T, { [K in keyof T]: T[K] extends V ? K : never }[keyof T]>;
class Bar<Foo> {
public boom<K extends KeysMatching<Foo, Function>>(first: K, second: Foo[K]) { }
}
// okay, the callback is (x: number) => void
new Bar<MyFoo>().boom("foo1", (x: number) => console.log(x.toFixed(2)));
// error, the callback is (x: number) => void but should be (x: string) => void
new Bar<MyFoo>().boom("foo2", (x: number) => console.log(x.toFixed(2)));
interface MyFoo { age: number }
// error, "age" is not accepted anymore
new Bar<MyFoo>().boom("age", 40); // error
希望对您有所帮助。祝你好运!
推荐阅读
- python - numpy 大整数失败
- perl - 从 db 值计算 perl cgi
- python - Tk() 和 Frame() 有什么区别?
- node.js - 使用 nodejs 生成数百万个模拟数据
- version-control - 您如何在 mercurial 中找到两个标签之间的变更集?
- arrays - 将 numpy 数组转换为 ctype 数组的最快方法是什么?
- php - Angular 应用程序中的 HttpErrorResponse | PHP API
- r - 过滤两个日期之间的数据框
- tomcat - Apache Tomcat 未在 Windows 7 中启动
- android - android api 23中的导航视图通货膨胀错误