我试图基于预先存在的实用程序类型构造一个函数类型,并简单地定义一个键到类型的Map:
type TypeMap = {
a: A;
b: B;
}
我尝试构建的类型是一个多签名函数类型,在第一个参数中使用key作为文本字符串:
type Result = {
(key: "a"): A;
(key: "b"): B;
}
这在TypeScript中是可能的吗?我知道函数类型并不总是很好地与Map类型放在一起。
我可以这样做,但我希望避免重复完整的密钥列表:
type TempFunc<K extends keyof TypeMap> = {
(key: K): TypeMap[K];
};
type Result = TempFunc<"a"> & TempFunc<"b">;
注意:这是我试图完成的一个非常简化的版本;我实际的TypeMap
有超过100个键。
2条答案
按热度按时间d7v8vwbk1#
TypeScript将具有多个调用签名的函数(也称为重载函数)视为等效于这些调用签名的交集。即:
行为与相同
这和
您可以通过使用这些
Result
定义中的任意一个测试以下代码来验证:所以如果我们可以通过编程来生成一个交集,它就相当于你所要求的。
幸运的是,我们可以通过一种条件类型推理技术来实现,这种技术涉及到类型参数在 * contravariant * 位置上(参见Difference between Variance, Covariance, Contravariance and Bivariance in TypeScript),这类似于Transform union type to intersection type的答案:
除了它是一个 * 分布式对象类型 *,如在ms/TS#47109中所创造的,其中我们在
TypeMap
的键上执行map,并立即执行index into与keyof typeMap
的Map类型,以获得一个并集(由于前面提到的逆变性,它成为一个交集)。但是你可能不需要多个调用签名,这取决于用例,因为每个调用签名都以相同的方式将输入Map到输出,通过indexing into
TypeMap
的一个键,你可以得到一个非常相似的函数类型,只有一个generic调用签名:这比上面的分配反变对象要简单得多,而且它的行为非常相似:
也许您的用例实际上 * 需要 * 多个不同的调用签名,但如果不是这样,我肯定会推荐在这里使用泛型。
Playground代码链接
mnemlml82#
试试这个: