You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建RxJS可复用日期格式转换操作符时遭遇TypeScript类型赋值错误的问题求助

创建RxJS可复用日期格式转换操作符时遭遇TypeScript类型赋值错误的问题求助

我现在想写一个可复用的RxJS操作符,用来把类型T的对象转换成类型Q的对象,核心是做日期格式转换。T和Q的键是完全一致的,只是部分属性的类型有差异。

我觉得大体思路是对的,但卡在TypeScript的类型问题上搞不定,代码如下:

export function convertDateTimeToluxon<T extends object, Q extends Record<keyof T, any>>(): (source: Observable<T>) => Observable<Q> {
  return (source: Observable<T>): Observable<Q> => source.pipe(
    map((object: T): Q => {
      const convertedObj: Q = {} as Q;
      Object.keys(object).forEach((key: string) => {
        const typedKeyT: keyof T = key as keyof T;
        if(DateTime.isDateTime(object[typedKeyT])) {
          convertedObj[typedKeyT] = DateTime.fromISO(object[typedKeyT]);
        } else {
          convertedObj[typedKeyT] = object[typedKeyT];
        }
      })
      return convertedObj;
    })
  )
}

问题出在这两行赋值代码上:

convertedObj[typedKeyT] = DateTime.fromISO(object[typedKeyT]);
convertedObj[typedKeyT] = object[typedKeyT];

TypeScript一直报错说T[key of T]不能赋值给Q[key of T],我猜是不是因为最上面定义的Record里用了any类型导致的?


我暂时想出了下面这个解决方案,肯定还有优化空间!其中一部分思路参考了下方Geoffrey的回答:

export function convertDateTimeToLuxon<T extends Record<keyof T, any>, Q extends Record<keyof T, any>>(): (source: Observable<T>) => Observable<Q> {
  return (source: Observable<T>): Observable<Q> => source.pipe(
    map((object: T): Q => {
      const convertedObj: Q = {} as Q;
      Object.keys(object).forEach((key) => {
        const typedKeyT: keyof T = key as keyof T;
        if (DateTime.isDateTime(object[typedKeyT])) {
          convertedObj[typedKeyT] = DateTime.fromISO(object[typedKeyT]) as Q[keyof T];
        } else {
          convertedObj[typedKeyT] = object[typedKeyT];
        }
      })
      return convertedObj;
    })
  )
}

核心修改是在日期转换后的赋值语句里加了类型断言as Q[keyof T],明确告诉TypeScript转换后的值符合Q类型对应键的类型要求,暂时解决了类型不匹配的报错。

备注:内容来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 13:28:13