如何在TypeScript中定义键关联返回类型的对象映射器类型?
实现精确类型的Transaction映射器
当然可以实现,我们可以利用TypeScript的映射类型来为Mapper定义精确的返回值类型,替代原来的any,让每个键对应的函数返回值严格匹配Transaction接口中对应字段的类型。
步骤1:定义精确的Mapper类型
首先替换原来的Mapper类型,用映射类型遍历Transaction的每个字段,为每个字段指定函数的返回值类型:
interface Transaction { amount: number; order_date: Date; id: string; } // 定义外部API原始数据的类型(可根据实际API结构细化,这里用Record<string, any>兼容大多数情况) type RawTransaction = Record<string, any>; // 精确的Mapper类型:每个字段对应一个函数,返回值严格匹配Transaction的对应类型 type Mapper = { [K in keyof Transaction]: (raw: RawTransaction) => Transaction[K]; };
这个类型会自动遍历Transaction的所有键K,为每个键生成一个函数类型:
- 函数接收原始API数据作为参数
- 返回值必须是
Transaction[K]对应的类型(比如amount对应的函数必须返回number,order_date返回Date)
步骤2:编写符合类型约束的映射器实例
现在定义ExternalAPIMapper时,TypeScript会严格检查每个函数的返回值类型,不符合的话会直接报错:
import dayjs from 'dayjs'; const ExternalAPIMapper: Mapper = { amount: (raw_transaction) => raw_transaction.sale_amount, order_date: ({ transaction_date }) => dayjs(transaction_date, 'YYYY.MM.DD').toDate(), id: ({ transaction_id }) => transaction_id };
步骤3:修正映射函数的类型问题
原来的mapNetworkTransaction存在类型初始化和字段遍历的问题,这里修正为类型安全的版本:
// 明确定义Transaction的字段数组,确保只遍历合法字段 const txnFields: Array<keyof Transaction> = ['amount', 'order_date', 'id']; const mapNetworkTransaction = ( object: RawTransaction, mapper: Mapper, ): Transaction => { // 用Partial<Transaction>初始化,避免空对象的类型报错 const txn: Partial<Transaction> = {}; for (const txnField of txnFields) { const accessor = mapper[txnField]; if (accessor) { txn[txnField] = accessor(object); } } // 由于我们遍历了所有必填字段,可安全断言为Transaction类型 return txn as Transaction; };
可选优化:细化原始数据类型
如果外部API的返回结构是固定的,可以把RawTransaction定义得更具体,这样映射器里的函数会获得更精准的类型提示,避免拼写错误:
type RawTransaction = { sale_amount: number; transaction_date: string; transaction_id: string; // 其他API返回的字段 };
内容的提问来源于stack exchange,提问作者Paul Serre
相关产品推荐
相关产品推荐

