Typescript - 具有通用类型函数的索引签名
Posted
技术标签:
【中文标题】Typescript - 具有通用类型函数的索引签名【英文标题】:Typescript - index signatures with generically typed functions 【发布时间】:2020-12-24 12:43:52 【问题描述】:是否可以在 Typescript 中定义具有索引签名的接口,其中索引引用的属性值是同一泛型类型的不同类型?
让我试着解释一下:
我有一个具有以下通用签名的函数 Foo:
interface Foo<T> (arg1: Moo<T>): T
interface Moo<N> nest: N
然后是一个对象,它将由一堆 Foo 类型的函数组成,但每个函数都有不同的泛型参数。所以:
interface Foos
bar: Foo<number>,
baz: Foo<string>
const foos:Foos =
bar: x => x.nest,
baz: y => y.nest
但我不想在界面中明确定义每个函数。我想要类似的东西:
interface FoosTwo [K:string]: Foo<any>
const foosTwo:FoosTwo =
bar: x => x.nest,
baz: y => y.nest
但是,当然,如果我这样做,我在 foosTwo.bar 和 foosTwo.baz 上失去了任何类型的真正打字——它们都只是Foo<any>
。这是有道理的——编译器怎么知道我想要什么?
但是有没有办法告诉编译器 Foo 的泛型类型是什么,内联,即类似这样的东西(我意识到这不起作用)?
interface FoosTwo [K:string]: Foo<any>
const foosTwo:FoosTwo =
bar<number>: x => x.nest,
baz<string>: y => y.nest
换句话说,有没有办法给编译器提供足够的信息来确定 bar 是 Foo<number>
和 baz 是 Foo<string>
而无需为每个函数显式定义完整类型?
非常感谢
【问题讨论】:
不确定是否有帮助,但方法与***.com/a/63777650/1113002 中的方法相同。试试playground 是的,您和@jonrsharpe 在那篇文章中的 cmets 让我对索引字符串有了一点了解。我会玩一点,看看这是否能给我我需要的解决方案。谢谢! 【参考方案1】:根据上面@aleksey-l 的建议,我现在看到解决方案很简单。
将其视为索引签名的问题(这是我正在做的)是错误的。像 [K:string] 或 Record(string, any) 这样的索引签名必然是松散的,因为它们对于满足签名的任何内容都必须相同。这就是为什么我能做的最好的事情是interface FoosTwo [K:string]: Foo<any>
。
事实证明,我真正希望 TS 做的是推断一个强类型接口,就像我上面列出的手动接口:
interface Foos
bar: Foo<number>,
baz: Foo<string>
做到这一点的方法是使用标识函数和泛型让 TS 基本上吸收一些输入信息,然后使用它来输入最终函数。所以这个:
function createFoo<T>(func: Foo<T>):Foo<T>
return func
const foosTwo =
bar: createFoo<number>(x => x.nest),
baz: createFoo<string>( y => y.nest)
一个简单的标识函数,它使用泛型提供的“提示”以我想要的方式键入返回的(相同的)函数。 @alexksey-l 的解决方案同样有效,尽管它的表述与我提出的问题略有不同。他得到了答案(并且让我看到了使用泛型的一些力量)。
这里是 a playground 的完整解决方案。
【讨论】:
【参考方案2】:一个选项:
const foosTwo =
bar: (x => x.nest) as Foo<number>,
baz: (y => y.nest) as Foo<string>
【讨论】:
谢谢。我想我希望尽可能避免铸造。该对象将具有由不同开发人员添加的功能,我宁愿推断功能接口而不是依靠人们提供正确的演员表。也就是说,我确实认为这是一种改进。以上是关于Typescript - 具有通用类型函数的索引签名的主要内容,如果未能解决你的问题,请参考以下文章
您如何定义具有键字符串索引但具有特定类型的已知键的 TypeScript 接口?