如何类型安全地为对象的Date类型属性应用转换函数?
类型安全地转换对象中的Date属性
我尝试为对象中指定的Date类型属性应用类型为(dt: Date) => Date的转换函数,希望尽可能保证类型安全。目前已写出如下代码:
const transform = (dt: Date) => dt; function process<T extends { [k in K]: Date }, K extends keyof T>(obj: T, ...props: K[]) { props.forEach(p => (obj[p] = transform(obj[p]))); }
但在赋值obj[p] = transform(obj[p])时出现错误提示:
Type 'Date' is not assignable to type 'T[K]'.
不过transform(obj[p])并未触发类型报错,请问该如何修改这个函数使其正常工作?
问题原因
TypeScript类型系统中,T[K]被约束为Date的子类型(虽然JavaScript原生Date没有子类,但TS允许定义继承自Date的自定义类型),而transform返回的是基础Date类型,无法直接赋值给可能更具体的T[K]类型。
解决方法
方法一:让转换函数保留子类型信息
给transform添加泛型约束,使其返回值类型与输入值的子类型一致:
const transform = <D extends Date>(dt: D): D => dt; function process<T extends { [k in K]: Date }, K extends keyof T>(obj: T, ...props: K[]) { props.forEach(p => (obj[p] = transform(obj[p]))); }
这种方式更严谨,能保留T[K]的具体子类型信息,适合需要处理Date子类的场景。
方法二:使用类型断言明确类型
如果确定T[K]就是基础Date类型,没有子类扩展,可以在赋值时用类型断言告诉TypeScript返回值符合T[K]类型:
const transform = (dt: Date) => dt; function process<T extends { [k in K]: Date }, K extends keyof T>(obj: T, ...props: K[]) { props.forEach(p => (obj[p] = transform(obj[p]) as T[K])); }
这种方式更直接,适合场景简单、无需考虑Date子类的情况。
内容的提问来源于stack exchange,提问作者dcg
相关产品推荐
相关产品推荐

