[英]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 键?
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
}
}
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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.