TypeScript 3.1:如何在严格模式下用枚举索引数组?

时间:2018-10-02 10:38:43

标签: typescript

由于“ noImplicitAny”而启用TypeScript“严格”模式时,此代码无法编译。

您能告诉我如何声明/使用以Enum值索引的数组吗?

namespace CommandLineParser {
    enum States { sNoWhere, sSwitchValue }

    abstract class State {        
    }

    class NoWhereState extends State {

    }

    class SwitchValueState extends State {

    }

    export class GetOption {
        state: State;
        states: Array<State>[States];

        constructor() {
            this.states = new Array(2);
            this.states[States.sNoWhere] = new NoWhereState();
            this.states[States.sSwitchValue] = new SwitchValueState();
            this.state = this.states[States.sNoWhere];
        }
    }
}

let go = new CommandLineParser.GetOption();

错误是:

错误TS7017:元素隐式地具有“ any”类型,因为类型“ State”没有索引签名。

          this.states[States.sNoWhere] = new NoWhereState(this);
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

错误TS7017:元素隐式地具有“ any”类型,因为类型“ State”没有索引签名。

          this.states[States.sSwitchValue] = new SwitchValueState(this);
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

错误TS7017:元素隐式地具有“ any”类型,因为类型“ State”没有索引签名。

          this.state = this.states[States.sNoWhere];
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1 个答案:

答案 0 :(得分:1)

问题是states的类型。您定义了一个State数组,但随后使用了类型查询,其结果将为State。由于this.states = new Array(2);类没有成员,因此分配State成功,因此从技术上讲,数组满足类签名。

这将起作用:

export class GetOption {
    state: State;
    states: Array<State>;

    constructor() {
        this.states = new Array(2);
        this.states[States.sNoWhere] = new NoWhereState();
        this.states[States.sSwitchValue] = new SwitchValueState();
        this.state = this.states[States.sNoWhere];
    }
}

现在,这的确意味着您可以通过任意数字索引到数组中,而不仅限于枚举的type元素(可能不是您想要的)。如果您确实不需要数组方法,那么一个简单的对象可能会更好,尽管您必须立即将其全部初始化(或使用类型断言使其适合this.states = {} as any):

export class GetOption {
    state: State;
    states: Record<States, State>;

    constructor() {
        this.states = {
            [States.sNoWhere]: new NoWhereState(),
            [States.sSwitchValue] : new SwitchValueState()
        }
        this.state = this.states[States.sNoWhere];
        this.state = this.states[10]; //error
    }
}

元组类型也可以工作,因为枚举常量无论如何都对应于数字,如果需要它们,您将在其上获得Array方法:

export class GetOption {
    state: State;
    states: [State, State];

    constructor() {
        this.states = [new NoWhereState, new SwitchValueState]
        this.state = this.states[States.sNoWhere];
        this.state = this.states[10]; //error
    }
}