【发布时间】:2019-10-02 12:28:59
【问题描述】:
如何去掉or操作符(|),合并所有对象属性,让所有对象都可以访问?
因为现在,输入payload.signInMethod TS 抱怨这种方法不存在于任何“或组”中,而是这个。如何编写类型来合并所有对象键?
【问题讨论】:
-
我发布了游乐场
标签: typescript
如何去掉or操作符(|),合并所有对象属性,让所有对象都可以访问?
因为现在,输入payload.signInMethod TS 抱怨这种方法不存在于任何“或组”中,而是这个。如何编写类型来合并所有对象键?
【问题讨论】:
标签: typescript
处理联合类型的常用方法是使用类型保护将联合缩小到其中一个成员。在这种情况下,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
}
}
现在,如果您真的想直接访问 payload 上的所有成员,则必须有一些 | undefined 进入属性类型(因为属性可能是特定联合成员上的 undefined)。我们可以从 here 改编 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
}
【讨论】: