首页 > 解决方案 > 键入两个对象以确保它们不共享任何键

问题描述

我想写一个有两个参数的函数,每个参数都是一个对象。这些对象不得共享密钥。如何键入此约束?

// helpers
const a=1, b=2, c=3, d=4;

// how do I type this function?
function func(x, y) {/*...*/}

func({a, b, c}, {d}) // ok; no keys are shared
func({a, b}, {b, c}) // Error; key `b` is shared.

或者提出:我如何约束一个类型,使其不包含另一种类型的键?

const foo = {a, b};
type X = typeof foo;
type NoKeysOf<S> = {/*... */}; // <- How do I constrin this type?
const bar: NoKeysOf<X> = {d};   // ok; no keys shared
const baz: NoKeysOf<X> = {b, c} // Error; `b` is shared

标签: typescripttypes

解决方案


您可以在编译时使用never类型强制执行这种约束。

declare function f<
  A,
  B extends { [K in keyof B]: K extends keyof A ? never : B[K] }
>(
  a: A, b: B
): any

我们在这里要说的是,如果K是 的一个键B,扩展了 的一个键A,则其对应的值 inb将是类型never(因此,您永远无法构造它),否则,它将只是B[K]

这正是所需的行为:

const a = 1, b = 2, c = 3, d = 4;
f({ a, b, c }, { d }) // OK
f({ a, b }, { b, c }) // Error: Type 'number' is not assignable to type 'never'

游乐场链接


推荐阅读