简体   繁体   English

object Typescript 中的合并或运算符

[英]Merge or operator in object Typescript

How to get rid of or operator ( | ) and merge all object properties to be all accessible?如何摆脱或运算符( | )并合并所有 object 属性以供所有人访问?

Because now, typing payload.signInMethod TS complaints that this method does not exist in none "or group" but this one.因为现在,输入payload.signInMethod TS 抱怨这个方法不存在于任何“或组”中,而是这个。 How to write type to merge all object keys?如何编写类型以合并所有 object 键?

删除 ors

Desired object:所需的 object: 在此处输入图像描述

Playground to reproduce my problem: https://www.typescriptlang.org/play/#code/C4TwDgpgBAwg9gO2BAHsKBeKBvAUFKAUQDcIkBBMMAGwEsBjAQ2FsQC4d8CpGq6mWiAAoALRgGcIHccABOtBAHMA3FwC+qggGVaihAEkEAJQgAzDnm5RxugwgCyEYCLgATDgHJFcOIuoQPKAAfKA9TRnoIACMfAGtAkI8QRhc4BNCAV0lZBEYAWwDNKA0uQhQwWQhxcRgRCHpYuAzgCy4CMEYQAqRHZzchSskkDhi4f0YEIoJxEVoqBUVyV1dB8QGqshaoUfHJtqhKyNpSIUZZYAQIWUI8xlpqcRGfXamoCrg8uHhXKWs5BaKalwQNw9EQMigiic8CQqHQWAAFB0QNQ4Ix3LBEMg0ABtWIQEBwUyY2FoAC6AEpMAA+TjtTqo9EAOhsekMvRcrmUUAA9DyoAAJOAAdygwDgkKcB1origRLFs3EUCusjgsmBQA Playground to reproduce my problem: https://www.typescriptlang.org/play/#code/C4TwDgpgBAwg9gO2BAHsKBeKBvAUFKAUQDcIkBBMMAGwEsBjAQ2FsQC4d8CpGq6mWiAAoALRgGcIHccABOtBAHMA3FwC+qggGVaihAEkEAJQgAzDnm5RxugwgCyEYCLgATDgHJFcOIuoQPKAAfKA9TRnoIACMfAGtAkI8QRhc4BNCAV0lZBEYAWwDNKA0uQhQwWQhxcRgRCHpYuAzgCy4CMEYQAqRHZzchSskkDhi4f0YEIoJxEVoqBUVyV1dB8QGqshaoUfHJtqhKyNpSIUZZYAQIWUI8xlpqcRGfXamoCrg8uHhXKWs5BaKalwQNw9EQMigiic8CQqHQWAAFB0QNQ4Ix3LBEMg0ABtWIQEBwUyY2FoAC6AEpMAA+TjtTqo9EAOhsekMvRcrmUUAA9DyoAAJOAAdygwDgkKcB1origRLFs3EUCusjgsmBQA

The usual way to deal with union types is to use type guards to narrow the union down to one of the members.处理联合类型的常用方法是使用类型保护将联合缩小到其中一个成员。 In this case the in type guard works best:在这种情况下, in类型保护效果最好:

type Context = {
  EventApplication: {
    applicationPhase: string;
  };
  SignInRef: {
    signInMethod: 'google' | 'facebook' | 'yahoo' | 'username';
  };
  ExpressCheckout: {
    paymentMethodPresent: boolean;
    shippingAddressPresent: boolean;
    receivePartnerEmails: boolean;
    promoCode: string;
  }
}

const getContext = (payload: Context[keyof Context]) => {
  if('signInMethod' in payload) {
    payload.signInMethod; 
  } else if('applicationPhase' in payload) {
    payload.applicationPhase
  } else{
    payload.promoCode
  }
}

Play

Now if you really want to have access to all members directly on payload , some | undefined现在,如果您真的想直接在payload上访问所有成员,一些| undefined | undefined will by necessity have to creep into the property types (since a property might be undefined on a specific union member). | undefined必然会渗透到属性类型中(因为属性可能在特定的联合成员上undefined )。 We can adapt StrictUnion from here to get the types to work the way you want:我们可以从这里调整StrictUnion以使类型以您想要的方式工作:

type UnionKeys<T> = T extends any ? keyof T : never;
type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, undefined>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>

type Context = {
  EventApplication: {
    applicationPhase: string;
  };
  SignInRef: {
    signInMethod: 'google' | 'facebook' | 'yahoo' | 'username';
  };
  ExpressCheckout: {
    paymentMethodPresent: boolean;
    shippingAddressPresent: boolean;
    receivePartnerEmails: boolean;
    promoCode: string;
  }
}

const getContext = (payload: StrictUnion<Context[keyof Context]>) => {
  payload.applicationPhase // string | undefined 
}

Play

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM