如何为映射类型添加索引签名?

Stu*_*art 11 typescript mapped-types index-signature

假设我有界面

interface X {
   a: string;
   b: number;
   c: boolean;
}
Run Code Online (Sandbox Code Playgroud)

和一个功能

function values(x: X) {
   return Object.keys(x).map(s => x[s])
}
Run Code Online (Sandbox Code Playgroud)

当我启用typescript的strict标志时,我得到错误"元素隐式具有'任何'类型,因为类型'X'没有索引签名".因此,为了使其明确,我可以只为X的定义添加索引签名

[key: string]: any;
Run Code Online (Sandbox Code Playgroud)

十分简单.


但是,如果IX现在是映射类型,则:

type X<T> = {
  [P in keyof T]: string;
}
Run Code Online (Sandbox Code Playgroud)

我有这个功能

function values<T>(x: X<T>) {
  return Object.keys(x).map(s => x[s])
}
Run Code Online (Sandbox Code Playgroud)

我应该在哪里添加索引签名?有没有办法让这个明确,而不诉诸做一些粗略的事情Object.keys(x).map(s => (x as any)[s])

Mel*_*igy 10

您可以:

interface X {
    a: string;
    b: number;
    c: boolean;
    [key: string]: X[keyof X];
}
Run Code Online (Sandbox Code Playgroud)

现在的结果X[keyof X](string | number | boolean),这比any你的函数返回更好(string | number | boolean)[].

应该使用这两个示例的另一种方法是:

function values(x: X) {
    const keys = Object.keys(x) as (keyof X)[];
    return keys.map(s => x[s]);
}
Run Code Online (Sandbox Code Playgroud)

不漂亮,但至少比打字更好(x as any).

当然它也可以是通用的:

function values<T>(x: T) {
    const keys = Object.keys(x) as (keyof T)[];
    return keys.map(s => x[s]);
}
Run Code Online (Sandbox Code Playgroud)