如何为映射类型添加索引签名? [英] How do I add an index signature for a mapped type?
问题描述
假设我有接口
interface X {
a: string;
b: number;
c: boolean;
}
和一个函数
function values(x: X) {
return Object.keys(x).map(s => x[s])
}
当我启用 typescript 的 strict
标志时,我收到错误元素隐式具有 'any' 类型,因为类型 'X' 没有索引签名".所以为了明确起见,我可以在 X 的定义中添加一个索引签名
When I enable typescript's strict
flag I get the error "Element implicitly has an 'any' type because type 'X' has no index signature". So to make it explicit, I can just add an index signature to the definition of X
[key: string]: any;
简单易行.
但是,如果 I X 现在是映射类型:
However if I X is now a mapped type instead:
type X<T> = {
[P in keyof T]: string;
}
我有这个功能
function values<T>(x: X<T>) {
return Object.keys(x).map(s => x[s])
}
我应该在哪里添加索引签名?有什么方法可以使这一点明确而不诉诸于像 Object.keys(x).map(s => (x as any)[s])
where am I supposed to add the index signature? Is there any way to make this explicit without resorting to doing something gross like Object.keys(x).map(s => (x as any)[s])
推荐答案
您可以:
interface X {
a: string;
b: number;
c: boolean;
[key: string]: X[keyof X];
}
X[keyof X]
的结果现在将是 (string | number | boolean)
,这比 any
效果更好,因为您的函数的返回将是 (string | number | boolean)[]
.
The result of X[keyof X]
will now be (string | number | boolean)
, which works even better than any
because the return of your function will be (string | number | boolean)[]
.
适用于这两个示例的另一种方法是:
Another way that should work with both examples is:
function values(x: X) {
const keys = Object.keys(x) as (keyof X)[];
return keys.map(s => x[s]);
}
不漂亮,但至少比 (x as any)
更有类型.
Not pretty, but at least more typed than (x as any)
.
当然也可以通用:
function values<T>(x: T) {
const keys = Object.keys(x) as (keyof T)[];
return keys.map(s => x[s]);
}
这篇关于如何为映射类型添加索引签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!