如何为映射类型添加索引签名?
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])
}
当我启用打字稿的 strict
标志时,我收到错误 "Element implicitly has an 'any' type because type 'X' has no index signature"。所以为了明确,我可以在 X
的定义中添加一个索引签名
[key: string]: any;
简单易行。
但是,如果 I X 现在是映射类型:
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])
这样粗暴的事情
您可以:
interface X {
a: string;
b: number;
c: boolean;
[key: string]: X[keyof X];
}
X[keyof X]
的结果现在将是 (string | number | boolean)
,它比 any
效果更好,因为您的函数的 return 将是 (string | number | boolean)[]
。
另一种适用于这两个示例的方法是:
function values(x: X) {
const keys = Object.keys(x) as (keyof X)[];
return keys.map(s => x[s]);
}
不漂亮,但至少比 (x as any)
更有型。
当然也可以做成通用的:
function values<T>(x: T) {
const keys = Object.keys(x) as (keyof T)[];
return keys.map(s => x[s]);
}
假设我有接口
interface X {
a: string;
b: number;
c: boolean;
}
和一个函数
function values(x: X) {
return Object.keys(x).map(s => x[s])
}
当我启用打字稿的 strict
标志时,我收到错误 "Element implicitly has an 'any' type because type 'X' has no index signature"。所以为了明确,我可以在 X
[key: string]: any;
简单易行。
但是,如果 I X 现在是映射类型:
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])
您可以:
interface X {
a: string;
b: number;
c: boolean;
[key: string]: X[keyof X];
}
X[keyof X]
的结果现在将是 (string | number | boolean)
,它比 any
效果更好,因为您的函数的 return 将是 (string | number | boolean)[]
。
另一种适用于这两个示例的方法是:
function values(x: X) {
const keys = Object.keys(x) as (keyof X)[];
return keys.map(s => x[s]);
}
不漂亮,但至少比 (x as any)
更有型。
当然也可以做成通用的:
function values<T>(x: T) {
const keys = Object.keys(x) as (keyof T)[];
return keys.map(s => x[s]);
}