【问题标题】:TypeScript 3.1 : How to index an Array with an Enum in strict mode?TypeScript 3.1:如何在严格模式下使用枚举索引数组?
【发布时间】:2019-03-07 11:34:41
【问题描述】:

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

你能告诉我如何声明/使用由枚举值索引的数组吗?

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:元素隐式具有“任何”类型,因为“状态”类型没有索引签名。

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

错误 TS7017:元素隐式具有“任何”类型,因为“状态”类型没有索引签名。

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

错误 TS7017:元素隐式具有“任何”类型,因为“状态”类型没有索引签名。

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

【问题讨论】:

  • 你想要一个数组有什么原因吗?一个对象会更好地工作

标签: typescript


【解决方案1】:

我知道这有点老了,并不能真正回答问题,但我发现在您的情况下使用对象而不是数组的方式更直观。考虑以下:

enum MyIndexingEnum { stateOne, stateTwo }
const someIndexedObject {
  [MyIndexingEnum.stateOne]: { /* stuff */ }
  [MyIndexingEnum.stateTwo]: { /* stuff */ }
}

/* Accessing stuff */
someIndexedObject[MyIndexingEnum.stateOne]

【讨论】:

    【解决方案2】:

    问题在于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];
        }
    }
    

    现在这确实意味着您可以通过任何数字索引到数组中,而不仅限于可能不是您想要的枚举类型元素。如果您真的不需要数组方法,一个简单的对象可能会更好,尽管您必须一次将其全部初始化(或使用类型断言使其适合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
        }
    }
    

    【讨论】:

    • 带有Record&lt;States, State&gt; 的版本就像一个魅力!非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2019-03-23
    • 2019-06-29
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多