typescript - 有没有办法获得通用剩余参数的交集类型?

标签 typescript

我编写了一个合并多个对象并返回的合并函数。

type A = { a: number };
type B = { b: number };
type C = { c: number };

const a: A = { a: 1 };
const b: B = { b: 2 };
const c: C = { c: 3 };

function merge<T extends any[]>(...args: T): { [k in keyof T]: T[k] } {
    return args.reduce((previous, current) => {
        return Object.assign(previous, current);
    });
}

const m = merge(a, b, c);

m.a;
m.b;
m.c;

我对 m 类型的期望是 A & B & C,但我在编译器中得到了 [A, B, C] ,它给了我错误。

Property 'a' does not exist on type '[A, B, C]'.ts(2339)

是否有正确的方法来声明我的合并函数的返回类型?

最佳答案

您需要的是 intersection数组元素的数量:

TS Playground

type ArrayIntersection<T extends readonly unknown[]> = T extends [infer Head, ...infer Rest] ?
  Head & ArrayIntersection<Rest>
  : unknown;

function merge <T extends readonly any[]>(...args: T): ArrayIntersection<T> {
  return args.reduce((previous, current) => {
    return Object.assign(previous, current);
  });
}

type A = { a: number };
type B = { b: number };
type C = { c: number };

declare const a: A;
declare const b: B;
declare const c: C;

const m = merge(a, b, c); // A & B & C

m.a; // number
m.b; // number
m.c; // number

请注意,不兼容的交叉类型(或具有类型不兼容的成员)将导致该类型的never:

declare const result: ArrayIntersection<[
  { a: string },
  { b: number },
  { person: { first: string } },
  { person: { last: string } },
  { b: string },
]>;

result.person; // { first: string; last: string; }
result.a; // string
result.b; // never

关于typescript - 有没有办法获得通用剩余参数的交集类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70499260/

相关文章:

reactjs - 为什么复选框事件处理程序中的 `MouseEvent` 不是通用的?

javascript - 我如何使用 javascript/jquery 在枚举中调用函数 js

javascript - 引用嵌套的 TypeScript 模块

javascript - 如何清除 Jest 模拟实现以进行下一步测试?

typescript - 如何在 TypeScript 中定义不透明类型?

angular - 浏览器后退按钮默认行为在停止传播时仍在执行

javascript - TypeScript 接口(interface)未定义

angular - 如何在 Angular 2 应用程序中翻译 Typescript 字符串?

typescript - 采用任何类型及其子类型的函数

javascript - 如何在angular2 webpack typescript 中包含第三方javascript库