Typescript和文本转换(toLowerCase)正在丢失我的类型



我的问题的简单再现:

const demo = {
aaa: 'aaa',
bbb: 'bbb',
}
const input = 'AAA'
console.log(demo[input.toLowerCase()])

游乐场

JS本身会起作用。它会将"AAA"更改为"AAA",这在演示对象中确实存在。但TS抛出错误:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ aaa: string; bbb: string; }'.

这是因为它将该值视为任何字符串,而不是"aaa"。所以TS不允许在它的编译器中进行任何文本转换?

这个大写值来自API(graphqlenum(,所以我无法更改它。另一方面,这个对象来自使用普通pascalCase键的库。那么,我如何在TS不满意的情况下连接两者呢?

您真正想要断言的是input.toLowerCase()会为映射demo生成一个有效的键。你可以这样表达:

console.log(demo[input.toLowerCase() as keyof typeof demo])

这将在周围的代码中为您提供完整的类型安全性。这很好:

let ok: 'aaa' | 'bbb' = demo[input.toLowerCase() as keyof typeof demo]

但这些都被拒绝了:

let error1: 'aaa' = demo[input.toLowerCase() as keyof typeof demo]
let error2: 'ccc' = demo[input.toLowerCase() as keyof typeof demo]

除了@Thomas在上面的回答中所说的之外,

无论何时使用Typescript,都应该清楚地定义variablesobjects的类型。

检查以下代码。

type d = {
[key: string]: string
}
const demo: d = {
aaa: 'aaa',
bbb: 'bbb',
}
const input: string = 'AAA'
console.log(demo[input.toLowerCase()])

最新更新