我正在實施event emitter,但遇到了打字稿打字問題。請告訴我如何使這項作業。
export type IEventMap = {
"mount": () => void;
"mounted": () => void;
"unmount": () => void;
"unmounted": () => void;
"test1": (stringArg: string) => void;
"test2": (numberArg: number) => void;
};
export type IEventNames = keyof IEventMap;
export type IEventFn<K extends IEventNames> = IEventMap[K];
export type IEventListeners = { [K in IEventNames]?: Set<IEventFn<K>> };
export default class Events {
private readonly listeners: IEventListeners = {};
public on <K extends IEventNames> (eventName: K, callback: IEventFn<K>) {
if (!this.listeners[eventName]) {
this.listeners[eventName] = new Set();
}
this.listeners[eventName].add(callback);
}
public off <K extends IEventNames> (eventName: K, callback: IEventFn<K>) {
if (this.listeners[eventName]) {
this.listeners[eventName].delete(callback);
}
}
public emit <K extends IEventNames> (eventName: K, ...args: Parameters<IEventFn<K>>) {
if (this.listeners[eventName]) {
this.listeners[eventName].forEach(callback => callback(...args));
}
}
}
// test
const events = new Events();
events.on("mount", () => {
console.log("mount");
});
events.on("test1", arg => {
console.log(arg);
});
events.on("test2", arg => {
console.log(arg);
});
events.emit("mount");
events.emit("test1", "test string");
events.emit("test2", 1);
錯誤
型別“Set<IEventFn>”不可分配給型別“IEventListeners[K]”。型別 'Set<IEventFn>' 不可分配給型別 'Set<() => void> & Set<() => void> & Set<() => void> & Set<() => void> & Set <(stringArg: string) => void> & Set<(numberArg: number) => void>'。型別“Set<IEventFn>”不可分配給型別“Set<() => void>”。型別“IEventFn”不可分配給型別“() => void”。鍵入'(() => void) | (() => 無效) | (() => 無效) | (() => 無效) | ((stringArg: string) => void) | ((numberArg: number) => void)' 不能分配給型別 '() => void'。型別 '(stringArg: string) => void' 不可分配給型別 '() => void'。
物件可能是“未定義的”。物件可能是“未定義的”。物件可能是“未定義的”。
擴展引數必須具有元組型別或傳遞給休息引數。
游樂場鏈接
uj5u.com熱心網友回復:
- 可互換的回呼實際上應該是 rest-args,所以
export type IEventFn<K extends IEventNames> = (...a: Parameters<IEventMap[K]>) => void;
修復了一半的錯誤
- 如果出于任何原因,ts 不記得型別,只需使用
?.
this.listeners[eventName]?.delete(callback);
- ts 不想分配不匹配的型別,請鍵入向下以便型別匹配
let l: { [KK in K]?: Set<IEventFn<KK>> } = this.listeners;
(l[eventName] ??= new Set<IEventFn<K>>()).add(callback);
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/516229.html
標籤:打字稿打字稿打字
上一篇:物件是相等的,即使屬性不相等
