Utilizing TypeScript 3.1: Easier Array Indexing with Enums in Strict Mode

Enabling TypeScript "strict" mode with "noImplicitAny" causes this code to fail compilation.

I am looking for guidance on how to properly declare and use Arrays indexed by Enum values.

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();

The errors encountered are :

error TS7017: Element implicitly has an 'any' type because type 'State' has no index signature.

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

error TS7017: Element implicitly has an 'any' type because type 'State' has no index signature.

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

error TS7017: Element implicitly has an 'any' type because type 'State' has no index signature.

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

Answer №1

Although this may seem a bit outdated and not directly addressing the question, I personally find it more intuitive to use objects instead of arrays in situations like yours. Take into consideration the following approach:

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

/* Retrieving data */
someIndexedObject[MyIndexingEnum.stateOne]

Answer №2

The issue lies in the data type of states. Initially, you define an array of type State, but later on, you utilize a type query which results in just State. The statement this.states = new Array(2); is successful because the State class does not have any members, allowing the array to technically fulfill the class signature.

To rectify this problem, consider the following solution:

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];
    }
}

It should be noted that with this approach, you can access the array using any number, not just limited to enum types, which may not align with your requirements. Alternatively, if you do not require the array methods, utilizing a simple object might be more suitable, albeit requiring initialization at once (or you can use a type assertion like 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
    }
}

Another viable option would be to use a tuple type since the enum constants correspond to numbers, and it offers access to array methods if needed:

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
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve recently appended DOM elements following the invocation of createComponent on a ViewContainerRef

I have a current function in my code that dynamically creates components and then generates a table of contents once the components are added to the DOM. This service retrieves all h3 elements from the DOM to include in the table of contents: generateDy ...

What kind of type is recommended to use when working with async dispatch in coding?

For my TypeScript and React project, I am currently working on an action file called loginAction.tsx. In this file, there is a specific line of code that handles the login functionality: export const login = (obj) => async dispatch => { dispatch( ...

Using React MUI Select in combination with react-hook-form does not seem to be compatible with Cypress testing

Within my React application, I have implemented a form that includes a dropdown select. Depending on the option selected from the dropdown, different input fields are rendered. const [templateType, setTemplateType] = useState(""); const { regi ...

Guide on initializing a Redux toolkit state with an array of objects or local storage using TypeScript

Currently, I am attempting to set an initial state (items) to an array of objects or retrieve the same from localStorage. However, I am encountering the following error. Type 'number' is not assignable to type '{ id: string; price: number; ...

What is the process for importing WebAssembly functions into TypeScript?

I currently have a TypeScript project and am in the process of incorporating a WebAssembly Module to replace certain functionalities. Successfully importing the WebAssembly module involved moving the .wasm loading logic to its own .js file, which is then ...

Is there a way to invoke a function within a mat-error element?

I need to display an error message in my input field! The function will return true if both passwords match, otherwise it will return false. How can I invoke a boolean function inside mat-error! My Function: checkPasswords(): Boolean { // 'passwords& ...

Tips for bypassing arrow functions when sending prop values to another component?

**Stateful ApplicatorType Component** class ApplicatorType extends Component { public state = { applicatorTypes: ['Carpenter', 'Painter', 'Plumber'], applicatorTypesSelected: [], } public render() { allotedTypes = ( &l ...

Omit functions from category

This question reminds me of another question I came across, but it's not quite the same and I'm still struggling to figure it out. Basically, I need to duplicate a data structure but remove all the methods from it. interface XYZ { x: number; ...

The member 'email' is not found in the promise type 'KindeUser | null'

I'm currently developing a chat feature that includes PDF document integration, using '@kinde-oss/kinde-auth-nextjs/server' for authentication. When trying to retrieve the 'email' property from the user object obtained through &apo ...

Is it possible to customize webpack 4 modules in order to enable Jasmine to spy on their properties?

I've been facing issues trying to run my Jasmine test suite with webpack 4. Ever since I upgraded webpack, I keep getting this error message in almost every test: Error: <spyOn> : getField is not declared writable or has no setter The problem ...

Uploading multiple files simultaneously in React

I am facing an issue with my React app where I am trying to upload multiple images using the provided code. The problem arises when console.log(e) displays a Progress Event object with all its values, but my state remains at default values of null, 0, and ...

Change prompt-sync from require to import syntax

In my Node project, I have integrated the prompt-sync module. const prompt = require('prompt-sync')(); const result = prompt(message); To maintain consistency in my TypeScript code, I decided to switch from using require to import. In order to ...

Displaying the ngFor data in the HTML section

Struggling with passing an array from poll-vote.component.ts to poll-vote.component.html. The data involves radio buttons and I'm using ngFor loop with index, but it's not working as expected: Here is my poll-vote.component.ts code: import { Com ...

Creating a TypeScript interface where the type of one property is based on the type of another property

One of my Interfaces has the following structure: export enum SortValueType { String = 'string', Number = 'number', Date = 'date', } export interface SortConfig { key: string; direction: SortDirection; type: Sort ...

Ways to access UserProfile in a different Dialogio

For the implementation of a chatbot, I am utilizing Microsoft's Bot Builder framework. However, upon implementing an alternative path to the dialog flow, I noticed that the user's Profile references are getting lost. Here is the code snippet fr ...

Difficulty Determining Literal Types that Expand a Union of Basic Data Types

Below are the components and function I am working with: interface ILabel<T> { readonly label: string; readonly key: T } interface IProps<T> { readonly labels: Array<ILabel<T>>; readonly defaultValue: T; readonly onChange ...

Angular - Customizing button bindings for various functions

As a newcomer to Angular and TypeScript, I am faced with the task of creating a customizable button that can display text, an icon, or both. For example: button-icon-text-component.html <button> TEST BUTTON </button> app.component.html & ...

Launching npm start does not automatically open a browser tab

I'm currently learning angularjs 2 and I'm eager to create my first application using the framework. Following the guidelines on their official website, I proceeded with all the steps outlined in this link. In step 6, I am required to run the com ...

Here's a way to resolve the issue: ReactDOM.render() - TS2345 error: Cannot assign type '() => Element' to type 'ReactElement' in the argument

After tackling React-Router with Typescript, I encountered a typing issue that has me perplexed. Prior to this, I was using an older version of React and React-Router. But now, after updating to the latest builds using yarn, I'm facing this hurdle. ...

What are the distinctions between using getStaticPaths + getStaticProps and useRouter in NextJS?

I'm currently diving into the world of NextJS and finding myself puzzled by the distinctions between getStaticProps & getStaticPaths compared to utilizing useRouter().query. At this point, it appears to me that both methods serve a similar purpos ...