打字稿为什么我能够动态修改TypeScript对象

时间:2018-04-17 10:17:02

标签: typescript

-

更新:道歉,我更新了我的问题和代码,它缺少索引器 - 关键元素。

我有一个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???";

为什么这可能?索引器允许动态读/写,但我不想丢失类型安全。

1 个答案:

答案 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 正在放松限制,因为这是一个众所周知的痛点,但也有陷阱,这就是默认情况下没有启用的原因。