1

I've defined the following interface:

export interface Data {
  visibleAction: string
  actionsVisibility: {
    actionForms: boolean
    backButton: boolean
    createAccount: boolean
    login: boolean
  }
  actionsHistory: string[]
  userID: string
}

which is later implemented on the class:

export default class userManager extends Vue implements Data {
  actionsVisibility = {
    login: false,
    createAccount: false,
    backButton: false,
    actionForms: false
  }
  visibleAction = `login`
  actionsHistory = []
  userID = ``

  hideUserActionForm () {
    this.actionsVisibility[this.visibleAction] = false
  }
  ... other logic
}

For the line this.actionsVisibility[this.visibleAction] = false TS warns with the error:

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ login: boolean; createAccount: boolean; backButton: boolean; actionForms: boolean; }'.   No index signature with a parameter of type 'string' was found on type '{ login: boolean; createAccount: boolean; backButton: boolean; actionForms: boolean; }'.

Can you please suggest how approach the followin typecism :)

volna
  • 2,452
  • 4
  • 25
  • 61
  • Does this answer your question? [How do I prevent the error "Index signature of object type implicitly has an 'any' type" when compiling typescript with noImplicitAny flag enabled?](https://stackoverflow.com/questions/32968332/how-do-i-prevent-the-error-index-signature-of-object-type-implicitly-has-an-an) – Klaycon Dec 12 '19 at 22:07

1 Answers1

1

this.visibleAction in userManager class gets a string type in your case and you cannot use string to access this.actionsVisibility as computed property name, hence an error is triggered.

In addition, a TS design limitation is that class properties like visibleAction do not get a contextual type from base types like Data, so you need to annotate types in the class again. If you hover over the class properties, you notice that some do not match the interface types - more explanations in this answer.

A possible solution

Give visibleAction in Data and userManager an explicit type keyof Data["actionsVisibility"], which is the union of string keys of actionsVisibility (Playground):

export interface Data {
    visibleAction: keyof Data["actionsVisibility"] // change this type
    actionsVisibility: {
        actionForms: boolean
        backButton: boolean
        createAccount: boolean
        login: boolean
    }
    ...
}

export default class userManager implements Data {
    actionsVisibility = {
        login: false,
        createAccount: false,
        backButton: false,
        actionForms: false
    }
    visibleAction: keyof Data["actionsVisibility"] = `login` // change this type
    ...

    hideUserActionForm() {
        this.actionsVisibility[this.visibleAction] = false // works now
    }
}
ford04
  • 66,267
  • 20
  • 199
  • 171