The element is implicitly assigned an 'any' type due to the fact that a string or number type expression cannot be used to index the element's type

Greetings everyone! This is my debut post on Stack Overflow, so I'll do my best to articulate my issue clearly. I am currently working with a JSON file named phrases.JSON which has the following structure:

{
  "start": {
    "affirmative": [
      some strings
    ],
    "interrogative": [
     some strings
    ]
  },
  "mid": [
    some strings
  ]
}

After importing this JSON file as 'phrases' using

import phrases from '../utils/phrases.json'
, I declared it in modules.d.ts like so:

declare module '*.json' {
  const data: any
  export default data
}

To streamline my workflow, I crafted an interface for the imported phrases.json file as follows:

interface Phrases {
  [key: string]: TypePhrases | string[]
  start: TypePhrases
  mid: string[]
}
interface TypePhrases {
  [key: string]: string[]
  affirmative: string[]
  interrogative: string[]
}

In one of my classes, I implemented a function:

private getPhrases(position: string | number) {
    return phrases[position]
  }

When invoking this function within my class, I expect to retrieve the 'start' object when passing the string 'start', or an array of strings when passing 'mid'. For example:

const MID_STRING: string = 'mid'
console.log(this.getPhrases(MID_STRING)[0])

However, I encountered the following error in my return function:

Element implicitly has an 'any' type because expression of type 'string | number' can't be used to index type '{ "start": { "affirmative": string[]; "interrogative": string[]; }; "mid": string[]; }'. No index signature with a parameter of type 'string' was found on type '{ "start": { "affirmative": string[]; "interrogative": string[]; }; "mid": string[]; }'.

I would greatly appreciate any assistance in resolving this issue. I've attempted several approaches without success, and I'm now seeking help. Thank you!

Answer №1

The import object's type is determined by the contents of the `.json` file, rather than the types you specified. There doesn't appear to be a direct connection between the two. Also, the compiler does not use the `declare module '*.json'` definition when it locates the file on disk.

The issue you're encountering is actually quite straightforward. TypeScript is unable to verify that `phrase` is a valid key for indexing the `phrases` object.

You can utilize type assertions to make use of the defined types:

private getPhrases(position: string) {
    return (phrases as Phrases)[position]
}

m() {
    const MID_STRING = 'mid'
    var a = this.getPhrases(MID_STRING); // a is TypePhrases | string[]
    if (a instanceof Array) { // must use type guard to index
        a[0]
    }
}

Play

An alternative and safer approach would be to use `keyof` along with generics to access the correct type of value in the object. This method is only feasible if you typically use constants.

private getPhrases<K extends keyof typeof phrases>(position: K) {
    return phrases[position]
}

m() {
    const MID_STRING = 'mid' // no string annotation, MID_STRING is typed as 'mid'
    this.getPhrases(MID_STRING)[0]; // ts knows this returns string[] and we can index directly into it
}

Play

If you have a `string` that you want to use for indexing a type, you can also assert that the string is a `keyof` the type. This approach is not entirely type-safe but may sometimes be necessary:

private getPhrases(position: string) {
    return phrases[position as keyof typeof phrases]
}

Answer №2

Ensure that the array index is represented as an integer and not a string

private fetchPhrases(phrase:string, position: number) {
    return phrase[position]
  }

Additionally,

const MID_STRING: string = 'mid'
console.log(this.fetchPhrases(MID_STRING,0))

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

Navigating to the end of a list using Angular's scroll feature

I'm trying to figure out how to automatically scroll to the bottom of a list in TypeScript, can someone help me with this? Here's a similar example I found that uses jQuery (I specifically need it in TypeScript): Scroll to bottom of list wit ...

Ways to organize class and interface files within the same namespace in TypeScript

I'm tackling a Typescript query related to namespaces and organizing files. Within a single namespace, I have multiple interfaces and classes that I'd like to separate into individual .ts files. The goal is to then combine these files so that whe ...

What are the steps to effectively utilize npm warnings within tslint?

After using eslint for javascript files, I am now transitioning to tslint for TypeScript linting. With eslint, I could specify some errors as NPM warnings, such as console logging. https://i.sstatic.net/BNhy6.png I realize that my "warnings" are generat ...

What is the best way to transform a unicode string into JSON format?

Looking to transform the Unicode string below into a JSON Object. var str = '{"method_title":"Bank. Transfer","instructions":"Account Name: Sriram Me Co.,Ltd.\r\n-------------------------------------------- ...

What is the best way to preserve an enumeration value in TypeScript?

Is there a way to save enumeration values in TypeScript? For instance: createArticle(name: string, clr: ??enumeration??) { return axios.post(`${environment.apiUrl}/cards`, { card: `${name}`, color: ??clr?? }, ... } PS: Conte ...

Decrease the size of the mat-flat-button

I have a message board where I am trying to incorporate delete buttons. However, when using the mat-flat-button feature, it appears to be increasing the height of the message items. If I adjust the button's height to 50%, then the button becomes half ...

Exploring TypeScript: Ensuring Compatibility of Types

Given two sets of TypeScript type definitions in string format: Set A: { a: string b: number } Set B: { a: string } Is there a way to programmatically determine if these two sets are compatible? In other words, can we assign variables defi ...

Executing Typescript build process in VSCode on Windows 10 using Windows Subsystem for Linux

My configuration for VSCode (workspace settings in my case) is set up to utilize bash as the primary terminal: { "terminal.integrated.shell.windows": "C:\\WINDOWS\\Sysnative\\bash.exe" } This setup allo ...

Exporting symbols within the same namespace from multiple files in a TypeScript project

I have a typescript module and I am looking to define symbols within the 'aaa' namespace from multiple files. Here is an example of what my code looks like: a.ts: export namespace aaa { export const a = "a"; } b.ts: export namespac ...

Having trouble with the npm Fluid Player installation

I am attempting to integrate Fluid Player into my Angular application Using - npm i fluid-player However, I'm encountering this error ...

Having trouble passing a React Router Link component into the MuiLink within the theme

The MUI documentation explains that in order to utilize MuiLink as a component while also utilizing the routing capabilities of React Router, you need to include it as a Global theme link within your theme. An example is provided: import * as React from & ...

Issue with Angular2: The [routerLinkActive] directive does not update when using _router.navigate

My app includes several routerLinks that I have styled using [routerLinkActive]="['active']". Everything works perfectly when I click on one of the routerLinks to navigate. However, when I try to navigate using: this._router.navigate( [ thisUrl ...

Can you explain the concept of a type object in typescript?

Can you explain the concept of the type object and its use? Some say it's like a blackbox. Which approach is better, A or B, when dealing with a parameter that may have unknown types of object keys? A const modifyData: (data: object) => void = da ...

Typescript encounters ERROR TS1128: Expecting a declaration or statement

Having trouble with a TypeScript error in my game-details.component.ts file that I've been trying to fix for a couple of hours. It's showing up at line 26, column 54 and everything seems correct to me. Interestingly, when I press CTRL + S in my ...

Mistakes following update to Angular 4 from Angular 2

After upgrading from Angular2 to Angular4, I encountered these errors in the CLI. While my app continues to function after the upgrade, I am curious about possible solutions to resolve these errors. Any suggestions? https://i.stack.imgur.com/CyYqw.png He ...

A class featuring a unique property that holds a property belonging to a type <T extends Class>

Currently, I am in the process of developing an Engine class that is capable of taking a map of various Module classes upon its construction and instantiating them by passing itself. Subsequently, the created instances are then stored within the modules. T ...

problems encountered when testing azure containerclient.listblobsbyhierarchy using sinon

I have developed a REST endpoint with the code "/files/lookup", which is designed to receive a query parameter folderPath and return a list of files with details, excluding content but including metadata. The endpoint connects to Azure Blob Stora ...

What is the best way to dynamically set an ID in Angular using the pound symbol (#)?

I am currently developing a dynamic Angular 6 application that utilizes dynamic components. My approach involves using @ViewChild('<id>', { read: ViewContainerRef }) <id>; to reference the divs where I intend to populate with dynamic ...

Looking for a way to search for contacts by number in Nativescript? Learn how to use the `getContactsByNumber(number

Using the nativescript-contacts plugin with nativescript 5.0, Angular, and webpack. Is there a way to retrieve the contact name based on the phone number? The main issue is that I want to display a list of recent phone calls, but there is one problem. L ...

Building on Angular 7, generate a fresh object by extracting specific values from an existing object

My object structure is as follows: const Obj = "Value1": { "value1value": "1" }, "Value2": { "value2value": "2" }, "Value3": { "value3value": "3" }, "BTest": { "1": "1", "2": "2" }, "Value4": { "value4value": "value4value" }, "ATes ...