我有一个带有键入键的对象,我们称之为状态(StatusesType
)。
我需要迭代对象并将键传递给某个方法,期望相同类型StatusesType
的参数,让它为statusPrinter()
type StatusesType = 'PENDING' | 'APPROVED' | 'REJECTED';
type SomeMap = {
[key in StatusesType]?: number
}
const STATUSES: SomeMap = {
PENDING: 5,
REJECTED: 2,
};
function statusPrinter(val: StatusesType) {
console.log('- ', val);
}
Object.keys(STATUSES).forEach(status => {
statusPrinter(status);
});
但是当我调用statusPrinter(status);
时,TypeScript会返回此错误
error TS2345: Argument of type 'string' is not assignable to parameter of type 'StatusesType'.
如何传递此密钥保留类型?
我知道我可以用这个statusPrinter(<StatusesType>status);
强制TS,但我认为这是我应该做的最后一件事,我宁愿原生解决方案。
更新:如果无法使用Object.keys()
保留类型迭代对象键,我有哪些选项?有没有办法迭代保留类型的密钥,如果是这样 - 哪种方式最好?我没有修复Object.keys()
,但我想保留原始对象结构。
谢谢!
答案 0 :(得分:2)
Object.keys将返回一个键数组,键的类型为string。
因此Object.keys
的签名为key(object: {}): Array<string>
。因此,当您循环键时,status
的类型为字符串,而不是StatusesType
。
您可以将该类型转换为statusPrinter(status as StatusesType)
答案 1 :(得分:2)
使用内置ES2015 Map
类的简短和类型安全解决方案:
type StatusesType = 'PENDING' | 'APPROVED' | 'REJECTED';
const STATUSES = new Map<StatusesType, number>([
['PENDING', 5],
['REJECTED', 2],
]);
function statusPrinter(val: StatusesType) {
console.log('- ', val);
}
STATUSES.forEach((_, status) => statusPrinter(status));
答案 2 :(得分:1)
你可以用这样的迭代器来做到这一点:
function iterator<M, K extends keyof M>(map: M, cb: (key: keyof M, value: M[K]) => void) {
Object.keys(map).forEach((key: K) => cb(key, map[key]))
}
iterator(STATUSES, status => {
statusPrinter(status);
});