在Typescript中使用Object.keys时避免隐式“ any”类型

时间:2019-03-05 21:22:29

标签: javascript typescript

我有一个带有已键入键的对象,我想遍历它并保持其类型,避免出现“元素隐式为'any'类型,因为'ContactList'没有索引签名”。

我知道Typescript的GitHub页面对此进行了详细讨论,但是我在这里找不到任何解决方案。尝试用枚举和联合,但我仍然会收到错误。

带有枚举(playground)的示例

enum Names {
  Joe,
  Bill,
  Bob
}

type ContactList = {
  [key in Names]: {
    isFriend: boolean;
  }
}

const contactList: ContactList = {
  [Names.Joe]: {
    isFriend: true,
  },
  [Names.Bill]: {
    isFriend: false,
  },
  [Names.Bob]: {
    isFriend: true,
    },
};

Object.keys(contactList).forEach(name => {
    // turn on 'noImplicitAny' and get error
    console.log(contactList[name])
})

带有联合(playground)的示例

type Names = 'joe' | 'bill' | 'bob'

type ContactList = {
  [K in Names]: {
    isFriend: boolean;
  }
}

const contactList: ContactList = {
  joe: {
    isFriend: true,
  },
  bill: {
    isFriend: false,
  },
  bob: {
    isFriend: true,
    },
};

Object.keys(contactList).forEach(name => {
    // turn on 'noImplicitAny' and get error
    console.log(contactList[name])
})

无论哪种方式,我都告诉打字稿“该对象中唯一允许使用的键来自名称”,据我所知索引签名,[key in Names]应该是一个,所以我不确定为什么我看到一个错误。抱歉,如果这是一个菜鸟问题,那么我对TS还是有点绿色。谢谢。

1 个答案:

答案 0 :(得分:3)

由于Object.keys返回的属性可能比按类型实际包含的对象更多,因此其返回类型为intentionally,键入为string[]。否则,类型良好的代码会在运行时引发意外异常,例如explained in this answer

因此,您必须使索引类型适用于字符串:

type ContactList = {
  [key: string]: {
    isFriend: boolean;
  },
};

或者您打字并希望最好:

contactList[name as Names]

您还可以:

console.log(...Object.values(contactList));