如何正确键入合并对象?

时间:2019-09-10 14:16:18

标签: typescript

我想写一个函数,其结果类型与对象散布操作类似。我不知道执行以下操作的好方法:

const one = {
  a: 'a',
};

const two = {
  b: 'b',
};

const three = {
  c: 'c',
};

const result = {
 ...one,
 ...two,
 ...three,
};
// the type for `result` is an object containing all three
// { a: 'a', b: 'b', c: 'c' };

const result = combine(one, two, three);
// I want the same result by using a function
// the typing result is an intersection though:
// { a: 'a' } & { b: 'b' } & { c: 'c' };

function combine<A>(a: A): A;
function combine<A, B>(a: A, b: B): A & B;
function combine<A, B, C>(a: A, b: B, c: C): A & B & C;
function combine(...args: any[]): any {
  const newObj = {};
  for (const obj of args) {
    for (const key in obj) {
      newObj[key] = obj[key];
    }
  }
  return newObj;
}

1 个答案:

答案 0 :(得分:1)

如果对象类型与静态已知键有交集,并且希望将其折叠为等效的单个对象类型,则可以这样操作:

type MergeIntersections<T> = T extends infer O ? {[K in keyof O]: O[K]} : never;

我正在使用type inference in conditional typesT复制到O,然后maps将类型中的O的属性复制到单个对象类型。 (复制并非总是必要的,但复制并不会受到伤害,有时会阻止编译器保留接口或类型名称。)

您可以这样使用它:

declare function combine<A>(a: A): MergeIntersections<A>;
declare function combine<A, B>(a: A, b: B): MergeIntersections<A & B>;
declare function combine<A, B, C>(a: A, b: B, c: C): MergeIntersections<A & B & C>;

const result = combine(one, two, three);
// const result: {a: string; b: string; c: string}

希望有所帮助;祝你好运!

Link to code