我最近在一个开源存储库中发现了以下代码字节:
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 中我也无法理解它。我把这段代码放在一个操场上,你可以在这里查看。
我最近在一个开源存储库中发现了以下代码字节:
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 中我也无法理解它。我把这段代码放在一个操场上,你可以在这里查看。
它是一个接受泛型参数的函数的接口。这是一个例子:
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;
}
现在我们可以正确地表示一个可以将 Employee 或 Room 或 Person(或其他任何东西)转换为数字的对象。