-
我有一个TypeScript类:
export class TestClass {
something: string = "";
[index: string]: any;
}
索引器是这样我可以动态读取/分配给现有类成员。例如。 test [something] ="嗨!&#34 ;;
然而,当我导入这个&在另一个TS类中使用,我能够做到:
var test: TestClass = new TestClass();
test.aPropertyNotInTheClass = "Why can I do this???";
为什么这可能?索引器允许动态读/写,但我不想丢失类型安全。
答案 0 :(得分:0)
索引器是这样我可以动态读取/分配给现有的类成员。例如。
System.Text.Encodings.Web.HtmlEncoder.Default.Encode()
我猜你在使用test[something] = "Hi!";
:
noImplicitAny
所以你添加了一个索引签名(如错误所示)以使错误消失:
class TestClass {
something: string = "";
}
const test: TestClass = new TestClass();
const key: string = "something";
test[key] // Error: Element implicitly has an 'any' type because type 'TestClass' has no index signature.
但是,正如您所见,这会更改类型以允许任何类型的访问,而不仅仅是已知属性。这不是你想要的。
真正的问题是您正在使用类型class TestClass {
something: string = "";
[index: string]: any;
}
的索引查找,因此编译器无法将其解析为已知属性(因为字符串可以是任何内容)。如果它是已知密钥,例如string
,则您不会收到任何错误:
"something"
这是有效的,因为const test: TestClass = new TestClass();
const key = "something";
test[key] // OK
是文字类型key
,而不是可以是任何内容的一般"something"
。因此,代码中的实际修复很可能是将类型已知密钥的密钥约束。您可以使用string
和地图类型来帮助您。
keyof
您拥有的另一个选项是使用compiler option function lookup(test: TestClass, key: keyof TestClass) {
return test[key]; // OK
}
lookup(test, "something"); // OK
lookup(test, "notInClass"); // Error
完全禁止隐式任何索引错误。这意味着在处理没有索引签名的类型时,您仍然只能使用具有已知属性的suppressImplicitAnyIndexErrors
属性访问权限,因此不允许使用.
,但可以使用使用任何键进行索引查找并且您将不会收到编译错误,您将获得类型test.aPropertyNotInTheClass
。但请记住,由于索引查找将为您提供any
类型,因此如果您不检查,则会出现运行时错误:
any
这是undefined
存在要防止的错误类型。 // with --suppressImplicitAnyIndexErrors
const test: TestClass = new TestClass();
const key = "aPropertyNotInTheClass";
test[key] // No compile error, but will be undefined
test[key].toUpperCase() // No compile error, but will be runtime error
正在放松限制,因为这是一个众所周知的痛点,但也有陷阱,这就是默认情况下没有启用的原因。