![](/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.