打字稿泛型错误地处理部分

Typescript generices incorrectly deals with partial

使用 typescript 3.7.2 时,我在以下函数中遇到错误:

function updateWithPartial <T,P extends Partial<T>, K extends keyof P> ( obj: T, part: P, key: K ) {
    return obj[key]=part[key]
}

因此,如果 key 是 keyof Partial ,它必须是 keyof T 你看到我错过了什么了吗?

在这种情况下,key 不是 keyof Partial<T> - 它的类型扩展了 keyof P,其中 P 扩展了 Partial<T>P 可能比 T 有 more/different 个键,所以 key 不能在这里用作 T 的 属性。

假设您不想向 T 添加新属性,则不需要类型参数 P,因为它可以从 T 本身推断出来。这里有两个解决方案,取决于您是否希望 objpart 获取 undefined 属性值:

// no undefined values assigned from part
function updateWithPartial<T, K extends keyof T>(obj: T, part: Partial<T>, key: K) {
  if (part[key] === undefined) throw new Error() // throw or do something else...
  return obj[key] = part[key] as T[K] // help compiler to understand, part[key] must be defined here
}

// possible undefined values assigned from part
function updatePartialWithPartial<T, K extends keyof T>(obj: Partial<T>, part: Partial<T>, key: K) {
  return obj[key] = part[key]
}

好的,一些测试:

declare const foo: { a: string }

const res = updateWithPartial(foo, { a: "bar" }, "a") // string 
const res2 = updatePartialWithPartial(foo, { a: "bar" }, "a") // string | undefined
const res22 = updatePartialWithPartial(foo, {}, "a") // string | undefined

Playground