typescript 类型“string”不能用于索引类型“T”,ts(2536)

fnatzsnv  于 2022-12-19  发布在  TypeScript
关注(0)|答案(2)|浏览(521)

我在result[key]上得到了上述错误

type DataType = Record<string, number>
export function getDifference<T extends DataType>(data1: T, data2: T): T {
  const keys = Object.keys(data1)
  return keys.reduce<T>((result, key) => {
    result[key] = data1[key] - data2[key]
    return result
  }, {})
}

我如何摆脱它,同时仍然返回泛型类型T,以便消费函数仍然接收正确的类型(而不是简单地将T更改为DataType)。

xv8emn3q

xv8emn3q1#

您需要手动为keys以及result[key]{}设置正确的类型,因为typescript无法正确地自动识别它们。

type DataType = Record<string, number>
export function getDifference<T extends DataType>(data1: T, data2: T): T {
  const keys: (keyof T)[] = Object.keys(data1)
  return keys.reduce<T>((result, key) => {
    if(typeof data1[key] === "number" && typeof data2[key]) { // Safeguard against object, array, etc. properties
        result[key] = data1[key] - data2[key] as T[keyof T]
    }
    return result
  }, {} as T)
}
``
doinxwow

doinxwow2#

对于那些有类似挑战的人来说,转换一个Record<string, string>而不是Record<string, number>,你需要一个额外的as来赋值给特定的键。

function transformRecords<T extends Record<string, string>>(
  records: T
): T {
  const keys: (keyof T)[] = Object.keys(records)
  return keys.reduce(
    (results, key) => {
      results[key] = records[key] + ' lol' as T[keyof T]
      return results
    },
    {} as T
  )
}

如果返回一个新的对象而不是修改,则可以避免额外的as

function transformRecords<T extends Record<string, string>>(
  records: T
): T {
  const keys: (keyof T)[] = Object.keys(records)
  return keys.reduce(
    (results, key) => ({
      ...results,
      [key]: records[key] + 'lol',
    }),
    {} as T
  )
}

如果你是用承诺来转变的:

async function transformRecords<T extends Record<string, string>>(
  records: T
): Promise<T> {
  const keys: (keyof T)[] = Object.keys(records)
  return await keys.reduce(
    async (results, key) => ({
      ...await results,
      [key]: records[key] + 'lol'
    }),
    Promise.resolve({} as T)
  )
}

相关问题