TypeScript:Object.keys 返回字符串 \[\]

新手上路,请多包涵

使用 Object.keys(obj) 时,返回值为 string[] ,而我想要一个 (keyof obj)[]

 const v = {
    a: 1,
    b: 2
}

Object.keys(v).reduce((accumulator, current) => {
    accumulator.push(v[current]);
    return accumulator;
}, []);

我有错误:

元素隐含地具有“任何”类型,因为类型 ‘{ a: number; b:号码; }’ 没有索引签名。

带有 strict: true 的 TypeScript 3.1。 Playground: 在这里,请勾选 Options 中的所有复选框以激活 strict: true

原文由 jeanpaul62 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 798
2 个回答

Object.keys 返回一个 string[] 。这是设计使然,如 本期 所述

这是故意的。 TS 中的类型是开放式的。因此,keysof 可能会少于您在运行时获得的所有属性。

有几种解决方案,最简单的一种是只使用类型断言:

 const v = {
    a: 1,
    b: 2
};

var values = (Object.keys(v) as Array<keyof typeof v>).reduce((accumulator, current) => {
    accumulator.push(v[current]);
    return accumulator;
}, [] as (typeof v[keyof typeof v])[]);

您还可以在 Object keys 创建一个别名,这将返回您想要的类型:

 export const v = {
    a: 1,
    b: 2
};

declare global {
    interface ObjectConstructor {
        typedKeys<T>(obj: T): Array<keyof T>
    }
}
Object.typedKeys = Object.keys as any

var values = Object.typedKeys(v).reduce((accumulator, current) => {
    accumulator.push(v[current]);
    return accumulator;
}, [] as (typeof v[keyof typeof v])[]);

原文由 Titian Cernicova-Dragomir 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是一个更准确的效用函数:

 const keys = Object.keys as <T>(obj: T) =>
    (keyof T extends infer U ? U extends string ? U : U extends number ? `${U}` : never : never)[];

Explanation: keyof T extends string | number | symbol , however Object.keys the symbol keys and returns number keys as strings.我们可以使用模板文字 `${U}` 将数字键转换为字符串。

使用这个 keys 实用程序:

 const o = {
    x: 5,
    4: 6,
    [Symbol('y')]: 7,
};
for(const key of keys(o)) {
    // key has type 'x' | '4'
}

原文由 JohnLock 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
Stack Overflow 翻译
子站问答
访问
宣传栏