元素隐式具有“任何”类型,因为类型“字符串”的表达式不能用于索引类型

时间:2019-12-12 22:03:55

标签: typescript vue.js

我已经定义了以下interface

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

稍后将在该类上实现:

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
}

对于行this.actionsVisibility[this.visibleAction] = false,TS发出错误警告:

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; }'.

能否请您提出如何处理跟进类型主义的方法:)

1 个答案:

答案 0 :(得分:1)

this.visibleAction类中的

userManager在您的情况下获得string类型,并且您不能使用string来访问this.actionsVisibility作为计算的属性名称,因此出错被触发。

此外,TS设计的局限性是诸如visibleAction之类的类属性不会从诸如Data之类的基类型中获得contextual type,因此您需要再次对类中的类型进行注释。如果将鼠标悬停在类属性上,则会注意到某些属性与接口类型不匹配-this answer中的更多说明。

可能的解决方案

visibleAction中的DatauserManager一个显式类型keyof Data["actionsVisibility"],它是actionsVisibilityPlayground)的字符串键的并集:

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