带泛型的 TypeScript 接口函数类型
我最近在一个开源仓库中找到了以下代码字节:
interface Use<I, C = context<I>> {
<O>(fn: avvio.Plugin<O, I>, options?: O): C;
}
简化为:
interface F<A> {
<B>(foo: A, bar: B): A;
}
我该如何调用 B 泛型?
我很难找到它的使用示例,即使在 TS Playground 中我也无法理解它。我把这段代码放在一个你可以查看的 Playground 中。
答案#1
这是一个接受通用参数的函数的接口。这里有一个例子:
const funcTwo: F<string> = <T>(foo: string, bar: T) => {
return `${foo} ${bar}`;
}
console.log(funcTwo('Hello', 7));
更新:添加一个实际的例子,可能会显示为什么它会有用。没有上下文要想出一个例子可能很难,但这是我不费太多心思的最佳尝试:
class UniqueCounter<T> {
private underlyingSet = new Set<T>();
constructor(
private hashingFunc: <V>(value: V) => T,
) {
}
add<V>(thing: V) {
const hash = this.hashingFunc(thing);
this.underlyingSet.add(hash);
}
count() {
return this.underlyingSet.size;
}
}
这个类尝试计算你拥有的某些东西的独特实例有多少。然而,默认的集合对对象使用===,这不是我想要的。相反,我为我的特定对象有某种哈希算法。不过,在某些情况下,我将哈希结果转换为字符串,而在其他情况下,我将其转换为数字(我哈希的结果是T)。
我不能将V添加到类泛型中,因为那样它就只能计算一种类型的对象。也许我可以通过使用我分配给所有这些类的一些唯一ID来对Person、Employee、Equipment和Room进行哈希处理。
我不能将 T 添加到哈希函数的类型参数中,因为我需要使用 T 来定义 underlyingSet。
更新2:
忽略之前的更新,因为它与手头的问题无关。你展示的类型:
interface F<A> {
<B>(foo: A, bar: B): A;
}
不等于:
interface F<A, B> {
(foo: A, bar: B): A;
}
假设我们有一个哈希工厂,它可以神奇地创建哈希对象,但它们只能哈希成一种类型的键。换句话说,你可以创建一个“将任何东西哈希为字符串”的对象,或者一个“将任何东西哈希为数字”的对象。我们可以将类定义为:
class HashingFactory<T> {
createHasher<V>(): Hasher;
}
然而,返回类型会是什么?我们如何定义 Hasher?如果我们将其定义为:
interface Hasher<K, V> {
hash(value: V): K;
}
那么我们正在创建一个只能对一种类型的输入进行哈希的东西(例如,它只能将 Employee 哈希为数字)。但是我们的神奇哈希器可以将任何对象哈希为数字。合适的接口应该是:
interface Hasher<K> {
<V>hash(value: V): K;
}
现在我们可以正确地表示一个可以将员工、房间或人(或其他任何东西)转换为数字的对象。
