基于函数参数的 TypeScript 动态函数定义
TypeScript dynamic Function definition based on functions argument
是否可以根据传递给函数的参数值更改某些东西的类型。对于带有回调的事件发射器,我需要这种类型。示例:
interface IUser {
name: string
}
type CallBack = /* the Type for the Callback that should be dynamic */
//for event1 the type CallBack should be (user: IUser) => any
use("event1", (user) => { /* check that event1 is used, so only add 1 argument to the callback type */ })
//for event2 the type CallBack should be (email: string, password: string) => any
use("event2", (email, password) => { /* check that event12is used, so add 2 argument to the callback type */ })
那么有没有办法检测使用了哪个事件并将正确的类型应用于回调?
最简单的方法是重载。
type CallBack = {
(name: "event1", cb: (u: IUser) => void): void
(name: "event2", cb: (email:string, pass: string) => void): void
}
let use: CallBack = null!;
//for event1 the type CallBack should be (user: IUser) => any
use("event1", (user) => { /* check that event1 is used, so only add 1 argument to the callback type */ })
//for event2 the type CallBack should be (email: string, password: string) => any
use("event2", (email, password) => { /* check that event12is used, so add 2 argument to the callback type */ })
如果您有更复杂的场景,例如已经有其他类型的回调,或者更复杂的条件,您可以考虑在剩余参数和条件类型中使用元组。但是从你的问题来看,那太过分了。
您可以使用这样的类型:
type CallBackEvent1 = (event: "event1", cb: (user: IUser) => void) => void;
type CallBackEvent2 = (
event: "event2",
cb: (email: string, pass: string) => void
) => void;
type CallBack = CallBackEvent1 | CallBackEvent2;
const callBack1: CallBack = (event: "event1", cb: (user: IUser) => void) =>
undefined;
const callBack2: CallBack = (
event: "event2",
cb: (email: string, pass: string) => void
) => undefined;
const wrongCallBack: CallBack = (event: "event2", cb: (user: IUser) => void) =>
undefined;
// Type '(event: "event2", cb: (user: IUser) => void) => undefined' is not assignable to type 'CallBack'.
// Type '(event: "event2", cb: (user: IUser) => void) => undefined' is not assignable to type 'CallBackEvent1'.
// Types of parameters 'event' and 'event' are incompatible.
// Type '"event1"' is not assignable to type '"event2"'.ts(2322)
是否可以根据传递给函数的参数值更改某些东西的类型。对于带有回调的事件发射器,我需要这种类型。示例:
interface IUser {
name: string
}
type CallBack = /* the Type for the Callback that should be dynamic */
//for event1 the type CallBack should be (user: IUser) => any
use("event1", (user) => { /* check that event1 is used, so only add 1 argument to the callback type */ })
//for event2 the type CallBack should be (email: string, password: string) => any
use("event2", (email, password) => { /* check that event12is used, so add 2 argument to the callback type */ })
那么有没有办法检测使用了哪个事件并将正确的类型应用于回调?
最简单的方法是重载。
type CallBack = {
(name: "event1", cb: (u: IUser) => void): void
(name: "event2", cb: (email:string, pass: string) => void): void
}
let use: CallBack = null!;
//for event1 the type CallBack should be (user: IUser) => any
use("event1", (user) => { /* check that event1 is used, so only add 1 argument to the callback type */ })
//for event2 the type CallBack should be (email: string, password: string) => any
use("event2", (email, password) => { /* check that event12is used, so add 2 argument to the callback type */ })
如果您有更复杂的场景,例如已经有其他类型的回调,或者更复杂的条件,您可以考虑在剩余参数和条件类型中使用元组。但是从你的问题来看,那太过分了。
您可以使用这样的类型:
type CallBackEvent1 = (event: "event1", cb: (user: IUser) => void) => void;
type CallBackEvent2 = (
event: "event2",
cb: (email: string, pass: string) => void
) => void;
type CallBack = CallBackEvent1 | CallBackEvent2;
const callBack1: CallBack = (event: "event1", cb: (user: IUser) => void) =>
undefined;
const callBack2: CallBack = (
event: "event2",
cb: (email: string, pass: string) => void
) => undefined;
const wrongCallBack: CallBack = (event: "event2", cb: (user: IUser) => void) =>
undefined;
// Type '(event: "event2", cb: (user: IUser) => void) => undefined' is not assignable to type 'CallBack'.
// Type '(event: "event2", cb: (user: IUser) => void) => undefined' is not assignable to type 'CallBackEvent1'.
// Types of parameters 'event' and 'event' are incompatible.
// Type '"event1"' is not assignable to type '"event2"'.ts(2322)