![](/img/trans.png)
[英]TypeScript: Why am I able to modify `readonly` property in constructor?
[英]Typescript why am i able to to dynamically modify TypeScript object
-
我有一个TypeScript类:
export class TestClass {
something: string = "";
[index: string]: any;
}
索引器使我可以动态地从现有的类成员读取/分配给现有的类成员。 例如test [something] =“ Hi!”;
但是,当我导入此代码并在另一个TS类中使用时,我可以执行以下操作:
var test: TestClass = new TestClass();
test.aPropertyNotInTheClass = "Why can I do this???";
为什么会这样呢? 索引器允许动态读/写,但是我不想失去类型安全性。
索引器使我可以动态地从现有的类成员读取/分配给现有的类成员。 例如
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
是因为key
是文字类型"something"
,而不是可能是任何东西的通用string
。 因此,代码中真正的解决方法很可能是将密钥限制为该类型的已知密钥 。 您可以使用keyof
和map类型来帮助您。
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
这是noImplicitAny
可以防止的错误类型。 该suppressImplicitAnyIndexErrors
松动现象的限制,因为这是一个已知的痛点,但配备的陷阱,这就是为什么它是不是默认启用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.