【发布时间】:2020-11-28 20:39:03
【问题描述】:
假设我有一个函数
function addField(obj, name, value) {
return { ...obj, [name]: value }
}
如何在 Typescript 中输入?编辑:我遇到了返回类型的问题。我希望它是“原来的 T,但其中包含这个 [name] 属性”。
我希望这可以工作,但不幸的是它没有:
function addField<T, V>(obj: T, name: string, value: V): T & { `${name}`: V } {
return { ...obj, [name]: value }
}
(它抱怨name 是一个值而不是一个类型)。所以,一种有效的破解方法是
// Hope that nameVal has only one key
function addField<T, V, N extends { [K: string]: V }>(
obj: T,
nameVal: N
): T & { [K in keyof N]: V } {
return { ...obj, ...nameVal };
}
但这仍然不是我想要的 100%(因为它允许添加多个字段),而且它也不是很好。有没有更好的方法可以动态地将字段添加到对象并将其编码到类型 systen 中?
EDIT2:我想我可以使用this 来禁止具有多个键的对象,但我还是想保留原来的addField(obj, name, value)。
【问题讨论】:
-
你不需要返回类型,typescript可以推断出来。 Playground example
-
@MikeS。我的错,我在两个最上面的例子中有一个错字。我希望将字段名称作为参数动态提供。在这种情况下,TS 不会自动推断类型(或者说,不够精细)
-
啊,那么this?唯一的问题是它允许重复的键,这可能不是你的意图
-
@MikeS。我想你不小心给我发了同一个文件。我只看到
function addField<T, K>(obj: T, name : string, value : K) { ... }。 -
很奇怪,对我来说不一样。我只是把它贴在这里
function addField<T, K extends { [key : string]: unknown }>(obj: T, value : K): T & K { return { ...obj, ...value }; }你不需要第三个类型参数,因为打字稿应该能够从使用中推断出来。至于多键的事情,第二个参数将覆盖字段,这可能是也可能不是你的意图(虽然它不会重复)
标签: typescript types