[英]Infering type of function argument based on other argument with discriminated union in TypeScript
我有一個描述事件類型的有區別的聯合。 然后我有addEventHandler
function ,它將事件 ID 作為第一個參數,將事件回調作為第二個參數。 事件 ID 字段是聯合類型的鑒別器。
interface TestEventA {
id: 'TestEventA';
payload: null;
}
interface TestEventB {
id: 'TestEventB';
payload: TestEventBPayload;
}
interface TestEventBPayload {
content: string;
}
interface TestEventC {
id: 'TestEventC';
payload: TestEventCPayload;
}
interface TestEventCPayload {
value: number;
}
type TestEvent = (TestEventA | TestEventB | TestEventC);
function addEventHandler<T extends TestEvent['id']>(eventId: T, listener: (data: (TestEvent & { id: T })) => void) {
eventEmitter.on(eventId, listener);
}
addEventHandler('TestEventC', (event) => {
// I want event to be of type TestEventC, but instead it is of type
// (TestEventA & { id: "TestEventC"; }) | (TestEventB & { id: "TestEventC"; }) | (TestEventC & { id: "TestEventC"; })
// event.payload: Object is possibly 'null'
// Property 'value' does not exist on type 'TestEventBPayload | TestEventCPayload'
console.log(event.payload.value);
if (event.id === 'TestEventC') { // redundant condition
console.log(event.payload.value); // No error here
}
});
如何使addEventHandler
回調 function 推斷事件的類型?
作為一種解決方法,您可以創建一個將事件 ID 映射到有效負載的接口,例如:
interface TestEventBPayload {
content: string;
}
interface TestEventCPayload {
value: number;
}
interface Events {
TestEventA: null,
TestEventB: TestEventBPayload,
TestEventC: TestEventCPayload
};
function addEventHandler<TId extends keyof Events>(
eventId: TId,
listener: (data: Events[TId] & { id: TId }) => void
): void {
eventEmitter.on(eventId, listener);
}
addEventHandler('TestEventC', (event) => {
console.log(event.value);
if (event.id === 'TestEventC') {
console.log(event.value);
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.