TypeScript报错TS2322:DeepPartial<T>[]无法赋值给T[]类型求解
TypeORM 泛型save方法类型报错解决
问题场景
开发中编写的通用TypeORM保存方法代码如下:
import { Repository } from 'typeorm' const save = async <T>(repo: Repository<T>, entities: T[]): Promise<T[]> => { return await repo.save(map((entity) => omit(['createdAt', 'updatedAt'], entity))(entities)) }
编译阶段抛出如下TS错误:
src/database/dao/user/user.dao.ts:46:3 - error TS2322: Type 'DeepPartial<T>[]' is not assignable to type 'T[]'. Type 'DeepPartial<T>' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'DeepPartial<T>'.
当前项目依赖版本:
- typescript: 4.7.3
- typeorm: 0.2.45
报错原因
- TypeORM 0.2.x 版本的类型定义中,
Repository.save()接收的入参类型、返回值类型均为DeepPartial<T> | DeepPartial<T>[],和方法声明的返回值Promise<T[]>存在天然类型差。 - 调用
omit移除实体的createdAt、updatedAt字段后,得到的对象缺少T类型的两个固定属性,不再满足完整的T类型约束,和save方法的泛型推导叠加后,触发了类型不匹配检查。
解决方法
方案1:类型断言(最简便,适配现有逻辑)
业务逻辑本身是合理的:移除自动维护的时间字段后传入save方法,TypeORM保存完成后会返回包含所有字段(自动生成ID、更新时间等)的完整实体,不存在运行时风险,直接通过类型断言修正TS类型即可:
import { Repository, DeepPartial } from 'typeorm' const save = async <T>(repo: Repository<T>, entities: T[]): Promise<T[]> => { const sanitizedData = map((entity) => omit(['createdAt', 'updatedAt'], entity))(entities) return (await repo.save(sanitizedData as DeepPartial<T>[])) as T[] }
方案2:加泛型约束(类型更严谨)
如果需要更严格的类型校验,可以给泛型加基础实体约束,明确实体结构:
import { Repository, DeepPartial } from 'typeorm' // 定义带公共时间字段的基础实体类型 interface BaseEntity { createdAt?: Date updatedAt?: Date } const save = async <T extends BaseEntity>(repo: Repository<T>, entities: T[]): Promise<T[]> => { const sanitizedData = entities.map(entity => omit(['createdAt', 'updatedAt'], entity)) as DeepPartial<T>[] return repo.save(sanitizedData) as Promise<T[]> }
说明:TypeORM 0.2版本的类型定义本身对泛型返回值的约束不够严谨,类型断言是该版本下的常规操作,升级到0.3.x版本后类型定义完善,可减少不必要的断言。
内容的提问来源于stack exchange,提问作者Romstar
相关产品推荐
相关产品推荐

