【发布时间】:2017-09-03 16:24:42
【问题描述】:
上下文:我正在尝试使用TypeState 库开发一种在打字稿中创建可扩展状态机的模式。 TypeState 为 Typescript 提供了一个类型安全的状态机,虽然不是我遇到的问题的核心,但它有助于说明我的目标。
问题:我在创建可扩展模式以在 Typescript 中扩展 enum 并在 interface 和 class 声明中实现它们时遇到问题。
目标:下面的伪代码说明了我希望我的模式是什么样的。
1) 定义基址enum States
2) 扩展 enum States 与其他状态导致 enum ExtendedStates
2) 使用States 和类型化状态机定义ParentInterface
3) 通过ChildInterface 扩展ParentInterface 并用ExtendedStates 覆盖States
4) 在class Parent 中实现ParentInterface
5) 在class Child 中扩展class Parent 实现ChildInterface
6) 能够从任一类调用broadcastState() 并获取当前状态。
我已经在其他语言中使用这种模式取得了很好的效果,如果能帮助我理解 Typescript 的局限性以及可以实现相同目标的任何替代模式,我将不胜感激。
import {TypeState} from "typestate";
enum States {
InitialState
}
// extends is not available on enum, looking for alternative
enum ExtendedStates extends States {
AdditionalState
}
/////////////////////////////////////////
// this works fine
interface ParentInterface {
fsm: TypeState.FiniteStateMachine<States>;
states: typeof States;
message: string;
}
// incorrectly extends ParentInterface, types of fsm/states are incompatible
interface ChildInterface extends ParentInterface {
fsm: TypeState.FiniteStateMachine<ExtendedStates>;
states: typeof ExtendedStates;
}
/////////////////////////////////////////
class Parent implements ParentInterface {
public fsm: TypeState.FiniteStateMachine<States>;
public states: typeof States;
public message: string = "The current state is: ";
constructor(state: States | undefined) {
state = state ? state : this.states.InitialState;
this.fsm = new TypeState.FiniteStateMachine(state);
this.broadcastCurrentState();
}
public broadcastCurrentState(): void {
console.log(this.message + this.fsm.currentState);
}
}
class Child extends Parent implements ChildInterface {
public fsm: TypeState.FiniteStateMachine<ExtendedStates>;
public states: typeof ExtendedStates;
constructor(state: ExtendedStates | undefined) {
state = state ? state : this.states.InitialState;
this.fsm = new TypeState.FiniteStateMachine(ExtendedStates);
this.broadcastCurrentState();
}
}
最近的一次
import {TypeState} from "typestate";
enum States {
InitialState
}
enum ExtendedStates {
InitialState,
ExtendedState
}
class Parent {
public fsm: TypeState.FiniteStateMachine<States>;
public states: typeof States;
public message: string = "The current state is: ";
// T is declared but never used
constructor(state: <T> | undefined) {
state = state ? state : this.states.InitialState;
// cannot find name T
this.fsm = new TypeState.FiniteStateMachine<T>(state);
this.broadcastCurrentState();
}
public broadcastCurrentState(): void {
console.log(this.message + this.fsm.currentState);
}
}
// types of fsm are incompatible
class Child extends Parent {
public fsm: TypeState.FiniteStateMachine<ExtendedStates>;
public states: typeof ExtendedStates;
constructor(state: ExtendedStates | undefined) {
// Param not assignable to type <T>
super(state);
}
}
此尝试接近预期结果,但无法编译并导致enum 中出现大量代码重复。它还丢失了接口,这些接口不是必需的,但确实提供了一个很好的安全网。
我很想听听大家的意见。我觉得这是一个强大的模式,我缺少一些简单的东西来实现它。
【问题讨论】:
标签: typescript enums typescript-typings