Typescript从联合类型转化到交叉合并后的对象类型

广告位招租
扫码页面底部二维码联系

我们有如下一个联合类型:

【未经授权禁止转载】【原创内容,转载请注明出处】转载请注明出处:www.tangshua【未经授权禁止转载】转载请注明出处:www.tangshuang.netng.net【原创内容,转载请注明出处】
type union = { a: string } | { b: number } | { c: boolean }

如何得到最终的类型:

【版权所有】唐霜 www.tangshu【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】ang.net【版权所有】唐霜 www.tangshu【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。ang.net
type obj = {
  a: string
  b: number
  c: boolean
}

如果是用js来写,不要太简单,但是typ转载请注明出处:www.tangshuang.net原创内容,盗版必究。escript没有对union的遍历能力著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】,所以只能走其他办法,经过探索后最终得到【作者:唐霜】【原创不易,请尊重版权】如下解:

【访问 www.tangshuang.n【未经授权禁止转载】转载请注明出处:www.tangshuang.netet 获取更多精彩内容】【原创内容,转载请注明出处】
type GetUnionKeys<Unoin> = Unoin extends any
  ? {
      [key in keyof Unoin]: key;
    } extends {
      [key in keyof Unoin]: infer K;
    }
    ? K
    : never
  : never;

type UnionToInterByKeys<Union, Keys extends string | number | symbol> = {
  [key in Keys]: Union extends any
    ? {
        [k in keyof Union]: k extends key ? Union[k] : never;
      } extends {
        [k in keyof Union]: infer P;
      }
      ? P
      : never
    : never;
};

type UnionToInter<Unoin> = UnionToInterByKeys<Unoin, GetUnionKeys<Unoin>>;

在使用时如下:

【本文受版权保护】【版权所有】唐霜 www.tangshu【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】ang.net原创内容,盗版必究。【本文首发于唐霜的博客】
type obj = UnionToInter<union>

这样就可以实现我们的目的。我写了两个原子未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】范型,GetUnionKeys用于获取联未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】合类型里面的全部key,UnionToI【转载请注明来源】【未经授权禁止转载】nterByKeys是关键,用于基于前面本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。获得的keys再得到最后的对象。

【转载请注明来源】转载请注明出处:www.tangshua【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】ng.net【本文首发于唐霜的博客】原创内容,盗版必究。

不过这个方法存在一定的风险,假如联合类型本文版权归作者所有,未经授权不得转载。【本文受版权保护】中存在相同的属性,那么可能存在不确定性,【转载请注明来源】【关注微信公众号:wwwtangshuangnet】比如:

原创内容,盗版必究。【版权所有,侵权必究】原创内容,盗版必究。【本文受版权保护】
type obj = UnionToInter<{ a: string, b: number } | { b: boolean }>

我们最终就会得到:

【版权所有】唐霜 www.tangshu本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】ang.net著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】
type obj = {
  a: string
  b: number | boolean
}

但是我们再开发中,常常会让后面一个覆盖前原创内容,盗版必究。转载请注明出处:www.tangshuang.net面的,我们期望得到的是:

【作者:唐霜】著作权归作者所有,禁止商业用途转载。
type obj = {
  a: string
  b: boolean
}

我之前在读一些博客的时候,有同学提到可以【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。通过冲载机制得到联合类型中的最后一个元素本文作者:唐霜,转载请注明出处。【作者:唐霜】,但是我没有找到这篇文章,如果你看到,请本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。在下方留言给我。

【版权所有,侵权必究】【版权所有】唐霜 www.tangshu【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。ang.net
已有2条评论
  1. 千劫 2022-07-21 15:11

  2. 1188 2022-05-17 11:30

    深奥, 我只会合并两个, 这种批量的就完全不会了.
    type UnionZ = {
      [k in (keyof A | keyof B)]: k extends keyof B ? B[k] : k extends keyof A ? A[k] : never;
    };