问题
首先我们定义一个 Event 对象
export type Event =
| {
type: 'CLICK';
}
| {
type: 'INPUT';
payload: {
value: string;
};
};
然后有这么一个函数
const sendEvent = (type: string, payload?: any) => {
// 具体方法的实现
};
我们预期这个函数应该是这样调用的:
sendEvent('CLICK');
sendEvent('INPUT', {
value: '123',
});
由于这个类型定义的比较宽泛,所以导致这个方法可以随意调用:
// should error
sendEvent('lalalala');
sendEvent('CLICK', 'aaa');
sendEvent('INPUT');
sendEvent('INPUT', {
value: 123,
});
所以我们需要重新定义下这个函数的参数类型。
解答
我们可以通过 infer 来根据第一个参数来推断出第二个参数的类型:
const sendEvent = <T extends Event['type']>(
...args: Extract<Event, { type: T }> extends { payload: infer Tpaylad }
? [type: T, payload: Tpaylad]
: [type: T]
) => {};