这有点复杂,因为
价值观
(函数参数)在运行时
类型
只有编译时。没有什么能阻止你通过考试
非常数
字符串到
idField
然而,你
可以
得到你想要的类型安全
如果将常量字符串传递给函数
.
让我们从一个基本示例开始(在javascript省略类型中)-
function foo(prop) {
return {
[prop]: 42
};
}
function foo<T extends string>(prop: T): Record<T, number> {
return {
[prop]: 42
} as Record<T, number>;
}
试穿一下
playground
这是怎么回事?我们先确定
prop
是一个扩展字符串的类型(也可以是常规的
T extends string | number | symbol
)-因为这是你需要使用的类型
道具
作为一个
财产
.
然后我们使用这个类型来创建返回类型
Record<T, number>
. 这和-
{
[k in T]: number
}
您可以使用或。
然而,这种断言是必要的。因为typescript不能强制参数始终是编译时常量。
let s = foo('userName');
// ^ Record<'userName', number>
s.userName; // all good
s.otherProp; // Property 'otherProp' does not exist on type 'Record<"userName", number>'
好的,现在我们用这个函数-
export const objectToArray = <T, K extends string>(
object: { [id: string]: T },
idField: K
): (T & Record<K, string>)[] => {
return Object.keys(object).map(key => ({ [idField]: key, ...object[key] })) as (T & Record<K, string>)[];
};
注意,我假设
K
(类型)
艾德菲尔德
)又是一根弦,你可以用
K extends string | number | symbol
取决于你的情况。我还假设房产的价值
K公司
是
string
,因此
Record<K, string>
试穿一下
playground