【发布时间】:2019-06-21 05:10:57
【问题描述】:
我不确定我是否在描述标题中当前的任务。 我想问的是来自以下要求。
我正在尝试对有限状态机的状态进行抽象,并提出以下定义(在打字稿中)
interface IState {
send<T, E>(message: T, callback?:(event: E)=>void): IState;
}
我试图表达一个有限状态机的状态应该能够接受消息并返回新状态,并带有一个可选的回调来处理转换期间的事件。
将该接口实现为具体状态时,出现问题。
例如,我正在尝试制作一个只有两种状态的简单状态机,LEFT 和 RIGHT,以及三个可能的消息 go-on ,左转,右转。下表显示了它们的关系。
关键是我想限制状态 LEFT 只接受 go-on 和 turn-right 消息,同时发送 turn-left to LEFT 应该是一个编译错误。
我尝试在 typescript 3.4.5 中实现如下。
class Left implements IState {
send(m: 'go-on', cb?: (e: never) => void): Left;
send(m: 'turn-right', cb?: (e: never) => void): Right;
send(m: 'go-on' | 'turn-right', cb?: any) {
return m === 'go-on' ? new Left() : new Right();
}
}
class Right implements IState {
send(m: 'go-on', cb?: (e: never) => void): Right;
send(m: 'turn-left', cb?: (e: never) => void): Left;
send(m: 'go-on' | 'turn-left', cb?: any) {
return m === 'go-on' ? new Right() : new Left();
}
}
实现没有编译错误,自动完成按预期工作。但是因为看起来很奇怪,所以我问了一个问题TypeScript function generic can only work for function overload with more than one signatures。
感谢您在该问题下的友好回复,我了解将重载函数分配给泛型函数是错误的。但是,如何在保持特定状态只接受所需类型的消息的同时表达状态的一般接口呢?
我能想到的另一个抽象是
interface IState<T, E, R extends IState<?, ?, ?>> {
send(message: T, callback?:(event: E)=>void): R;
}
但是返回类型是递归的,我不知道上面那三个问号要填什么。
一个更简单的版本可能是
interface IState<T, E> {
send(message: T, callback?:(event: E)=>void): IState<any, any>;
}
除了返回类型中烦人的 any 之外,它的行为似乎都一样。
interface IState {
send<T, E>(message: T, callback?:(event: E)=>void): IState;
}
我找到了maybe related issue in GitHub about generic value。
这个问题定义明确吗?
如果为真,上面列出的这些方法是否有正确的解决方案?
如果为假,正确的解决方案是什么?
【问题讨论】:
标签: typescript generics overloading parametric-polymorphism adhoc-polymorphism