考虑使用--noImplicitAny
编译的以下代码:
interface T {
ax: any,
bx: any,
}
const prefixes: ("a" | "b")[] = ["a", "b"];
const keys: ("ax" | "bx")[] = ["ax", "bx"];
const t: T = { ax: "foo", bx: "bar" };
for (const key of keys) {
const value = t[key]; // <- works
}
for (const prefix of prefixes) {
const value = t[prefix + "x"]; // <- TS7017 error
}
通过检查,我们可以看到两个for循环中的语句都应该有效。在第一个循环中,key
的类型与T
上的索引器的隐式类型完全匹配。在第二个循环中,prefix + "x"
的类型应该是所有权限("ax" | "bx")
,这也是所讨论的索引器的类型。
然而,tsc在第二个循环中引发TS7017错误(&#34; Element隐含地具有&#39;任何&#39;类型因为类型&#39; T&#39;没有索引签名。&#34; )。
我还能做些什么来进行类型检查,同时仍然保持类型安全性(所以,不只需要显式(t as any)
来使警告静音)?如果没有,是否有Github问题或跟踪此问题?
答案 0 :(得分:4)
不,遗憾的是,TypeScript不会从其他文字类型的操作中计算文字类型。
您需要使用类型断言。
const value = t[<keyof T>(prefix + "x")];
更详细地说,如果表达式的类型是"a"
而另一个表达式的类型是"b"
,并且我们将它们存储在变量x
和y
中分别表达式x + y
的类型将不为"ab"
。
如果这个 工作并且GitHub上存在许多未解决的问题,建议添加此功能或类似功能,那将是非常好的。有人甚至建议添加正则表达式文字类型,这可能有点极端,但组合文字类型对于链接生成和使用HTTP PATCH方法等场景非常有价值,例如,内部委托给的强类型包装函数fetch
。