打字稿泛型:T extends X 突然想要 X extend T
Typescript generics: T extends X all of a sudden wants X to extend T
我得到一个错误,我的接口 Event
应该实现 MyEvent
的所有属性,而实际上我希望 TS 检查 MyEvent
实现 Event
。
我对泛型的理解是我可以定义一个接受类型 T extends X
作为参数的函数,但现在它说 X doesn't extend T
.
背景
我正在创建一个简单的事件管理器:
// imports..
export interface Event {
getName: () => string;
}
export class EventManager {
private callbacks; // Typing is unimportant for this example.
on(eventName: string, cb: <T extends Event>(event: T) => void) {
// some code..
this.callbacks[eventName].push(cb);
}
// more code..
}
然后我尝试监听一个事件(它触发了一个让我感到困惑的错误):
class MyEvent implements Event {
// Implement Event interface method.
getName(): string {
return 'a';
}
// Add other random method.
getFooBar(): string {
return 'b';
}
}
const eventManager = new EventManager();
eventManager.on('test', (e: MyEvent) => {
console.log(e);
});
错误:
TS2345: Argument of type '(e: MyEvent) => void' is not assignable to parameter of type '<T extends Event>(event: T) => void'.
Types of parameters 'e' and 'event' are incompatible.
Type 'T' is not assignable to type 'MyEvent'.
Property 'getFooBar' is missing in type 'Event' but required in type 'MyEvent'.
这是怎么回事?我希望事件管理器接受任何类型的事件,因此 <T extends Event>
,但现在它说 Event
应该具有 MyEvent
的所有属性,而不是 MyEvent
应该具有所有 Event
接口?
(PS:如果我接受 Event
接口而不是接受类型 T
,也会发生同样的情况。
on
需要定义为泛型。像这样:
interface Event {
getName: () => string;
}
class EventManager {
private callbacks; // Typing is unimportant for this example.
on<T extends Event>(eventName: string, cb: (event: T) => void) {
// some code..
}
// more code..
}
class MyEvent implements Event {
// Implement Event interface method.
getName(): string {
return 'a';
}
// Add other random method.
getFooBar(): string {
return 'b';
}
}
class YourEvent implements Event {
// Implement Event interface method.
getName(): string {
return 'a';
}
// Add other random method.
getBarFoo(): string {
return 'b';
}
}
const eventManager = new EventManager();
eventManager.on<MyEvent>('test', (e: MyEvent) => {
console.log(e);
});
eventManager.on<YourEvent>('test', (e: YourEvent) => {
console.log(e);
});
我认为这只是你的语法错误。
我得到一个错误,我的接口 Event
应该实现 MyEvent
的所有属性,而实际上我希望 TS 检查 MyEvent
实现 Event
。
我对泛型的理解是我可以定义一个接受类型 T extends X
作为参数的函数,但现在它说 X doesn't extend T
.
背景
我正在创建一个简单的事件管理器:
// imports..
export interface Event {
getName: () => string;
}
export class EventManager {
private callbacks; // Typing is unimportant for this example.
on(eventName: string, cb: <T extends Event>(event: T) => void) {
// some code..
this.callbacks[eventName].push(cb);
}
// more code..
}
然后我尝试监听一个事件(它触发了一个让我感到困惑的错误):
class MyEvent implements Event {
// Implement Event interface method.
getName(): string {
return 'a';
}
// Add other random method.
getFooBar(): string {
return 'b';
}
}
const eventManager = new EventManager();
eventManager.on('test', (e: MyEvent) => {
console.log(e);
});
错误:
TS2345: Argument of type '(e: MyEvent) => void' is not assignable to parameter of type '<T extends Event>(event: T) => void'.
Types of parameters 'e' and 'event' are incompatible.
Type 'T' is not assignable to type 'MyEvent'.
Property 'getFooBar' is missing in type 'Event' but required in type 'MyEvent'.
这是怎么回事?我希望事件管理器接受任何类型的事件,因此 <T extends Event>
,但现在它说 Event
应该具有 MyEvent
的所有属性,而不是 MyEvent
应该具有所有 Event
接口?
(PS:如果我接受 Event
接口而不是接受类型 T
,也会发生同样的情况。
on
需要定义为泛型。像这样:
interface Event {
getName: () => string;
}
class EventManager {
private callbacks; // Typing is unimportant for this example.
on<T extends Event>(eventName: string, cb: (event: T) => void) {
// some code..
}
// more code..
}
class MyEvent implements Event {
// Implement Event interface method.
getName(): string {
return 'a';
}
// Add other random method.
getFooBar(): string {
return 'b';
}
}
class YourEvent implements Event {
// Implement Event interface method.
getName(): string {
return 'a';
}
// Add other random method.
getBarFoo(): string {
return 'b';
}
}
const eventManager = new EventManager();
eventManager.on<MyEvent>('test', (e: MyEvent) => {
console.log(e);
});
eventManager.on<YourEvent>('test', (e: YourEvent) => {
console.log(e);
});
我认为这只是你的语法错误。