20

假设我有接口

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 的定义中添加一个索引签名

[key: string]: any;

十分简单。


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

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])

4

1 回答 1

22

你可以:

interface X {
    a: string;
    b: number;
    c: boolean;
    [key: string]: X[keyof X];
}

X[keyof X]will 现在的结果是(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]);
}

不漂亮,但至少比(x as any).

当然它也可以通用:

function values<T>(x: T) {
    const keys = Object.keys(x) as (keyof T)[];
    return keys.map(s => x[s]);
}
于 2017-11-24T00:52:30.567 回答