如何处理TypeScript/JSDoc中属性赋值的类型转换问题
类型转换场景下的属性赋值解决方案
问题背景
先定义两个类型:
type FromType = { // 其他属性 value: string; } type ToType = Omit<FromType, 'value'> & { value: number; }
编写转换函数时,直接修改record.value会触发TypeScript报错,因为类型系统期望record.value是string类型:
/** * @param {FromType[]} records * @returns {ToType[]} records */ function transform(records){ return records.map((record) => { record.value = parseFloat(record.value); // 报错:类型number不能赋值给类型string return record; }); }
用Object.assign可以临时解决,但它会生成新对象,不符合性能要求:
/** * @param {FromType[]} records * @returns {ToType[]} records */ function transform(records){ return records.map((record) => { return Object.assign(record, { value: parseFloat(record.value), }); }); }
需要实现满足以下条件的类型转换:
- 允许安全修改原对象;
- 不将
FromType的value改为string | number联合类型; - 不创建新对象,保证性能。
可行方案:类型断言配合直接赋值
利用TypeScript的类型断言,明确告诉类型系统当前对象可以被当作ToType处理,从而直接修改属性值:
方案1:先断言对象类型再赋值
/** * @param {FromType[]} records * @returns {ToType[]} records */ function transform(records: FromType[]): ToType[] { return records.map((record) => { const typedRecord = record as ToType; typedRecord.value = parseFloat(record.value); return typedRecord; }); }
方案2:直接断言属性进行赋值
/** * @param {FromType[]} records * @returns {ToType[]} records */ function transform(records: FromType[]): ToType[] { return records.map((record) => { (record as ToType).value = parseFloat(record.value); return record as ToType; }); }
方案优势
- 直接修改原对象,无额外对象创建开销,满足性能要求;
FromType的类型定义保持纯净,无需改为联合类型;- 类型断言仅在编译期生效,运行时无额外逻辑,不会影响执行效率。
注意:使用此方案前,需确保业务逻辑中
parseFloat(record.value)的转换是安全的,且原对象确实可以被修改为ToType结构,避免运行时类型错误。
内容的提问来源于stack exchange,提问作者Kit Sunde
相关产品推荐
相关产品推荐

