typescript - 在对象上使用 reduce 时的类型问题
问题描述
我有一个函数试图返回一个对象,它使用所有 Pascal 大小写而不是 Camel 大小写的键接收。
我的接口:
export interface INodeMailerResponseLower {
accepted: string[];
rejected: string[];
envelopeTime: number;
messageTime: number;
messageSize: number;
response: string;
messageId: string;
}
export interface INodeMailerResponseUpper {
Accepted: string[];
Rejected: string[];
EnvelopeTime: number;
MessageTime: number;
MessageSize: number;
Response: string;
MessageId: string;
}
我的代码:
import { upperFirst } from 'lodash';
const response: INodeMailerResponseLower; // << insert object values here
const formattedResponse: INodeMailerResponseUpper = Object.keys(response).reduce((acc, key) => {
acc[upperFirst(key)] = response[key];
return acc;
}, {});
打字稿给我以下错误信息:
类型“{}”缺少类型“INodeMailerResponseUpper”中的以下属性:Accepted、Rejected、EnvelopeTime、MessageTime 和 3 个以上。ts(2740)
问题: 在做 reduce 时如何正确输入我的累加器?
解决方案
用于类型参数Partial<INodeMailerResponseUpper>
。reduce
这将意味着acc
具有该类型,并允许您为其分配属性。但是,您需要将结果转换为,INodeMailerResponseUpper
因为 TypeScript 不知道最终结果将包含所有必需的属性。
你可以这样做,它使用了相当多的类型断言:
const formattedResponse = Objectkeys(response)
.reduce<Partial<INodeMailerResponseUpper>>((acc, key) => {
(acc[upperFirst(key) as keyof INodeMailerResponseUpper] as unknown) =
response[key as keyof INodeMailerResponseLower];
return acc;
}, {}) as INodeMailerResponseUpper;
或者你也可以改进 lodash 的类型upperFirst
(使用 TypeScript 4.1):
declare module 'lodash' {
interface LoDashStatic {
upperFirst<S extends string = ''>(string?: S): Capitalize<S>;
}
}
const formattedResponse = (Object.keys(response) as (keyof INodeMailerResponseLower)[])
.reduce<Partial<INodeMailerResponseUpper>>((acc, key) => {
// Without the as unknown, TypeScript would complain that
// string | number | string[] is not assignable to undefined
(acc[upperFirst(key)] as unknown) = response[key];
return acc;
}, {}) as INodeMailerResponseUpper;
不幸的是,没有办法完全避免类型断言。
推荐阅读
- mysql - 自定义数据库结果 [Symfony 4]
- php - Symfony - 工作流组件 - 无法识别的选项“元数据”
- detection - 检测 AWS Elastic 部署失败
- typescript - MSBuild TypeScript 不重新生成所有 JS 文件
- nativescript - Nativescript - Onesignal 休息 API
- python-3.x - 从 S3 读取时出现 java.net.UnknownHostException
- javascript - 使用 JavaScript 搜索和更新数组中间的内容
- facebook-messenger - 如何禁用媒体选择器栏
- html - 删除所有内联 html 属性,但保留一些
- python - Pyinstaller 可执行文件仅适用于同一台机器 [python]