TypeScript和点符号访问对象

时间:2015-05-07 00:22:44

标签: javascript typescript

如果TypeScript是JavaScript的严格超集,为什么任意对象上的点符号都是错误的?我有JS代码,我想转换到TS以获得更好的类型安全性,但所有使用点表示法的访问(例如,myObj.thing)都给出了错误Property 'thing' does not exist on type '{}'.。当我使用括号表示法(例如,myObj['thing'])时,它可以正常工作。

Property does not exist on type

5 个答案:

答案 0 :(得分:8)

我知道你说这很奇怪,但这是TypeScript存在的主要原因之一。此错误有助于防止在对象上意外设置或获取不存在的属性。

现在,正如编译器告诉你的那样,bar上的属性x不存在,因为在编写{}时它已隐式输入var x = {};。< / p>

通过明确定义类型,可以告诉编译器x具有多于零的属性:

var x: { foo?: string; bar?: string; } = {};

现在,您可以在没有编译器抱怨的情况下获取或设置x.foox.bar。在大多数情况下,您可以将其移动到如下界面:

interface IFooBar {
    foo?: string;
    bar?: string;
}

var x: IFooBar = {};

x.foo = "asdf";  // ok
x.test = "asdf"; // error, as it should be

有些人建议你施放any,但不要偷懒。您应该充分利用TypeScript提供的类型系统。这样做绝对可以节省您在维护应用程序时的时间。

答案 1 :(得分:1)

由于Typescript对象的强类型特性,你可以使用&#34; any&#34;使它无类型:

var x: any = {};
x.bar = "bar";   /// ok

如果你需要的是定义文字属性的类型

var x: { [index: string]: TypeA } = {};

然后x["bar"]现在只能是TypeA的实例。

答案 2 :(得分:0)

x不包含任何名为bar的属性,因此您需要在对象中创建它:

function foobar() {
    var x = {

        foo: 'foo',
        bar: 'bar'
    }

    return x;
}

alert(foobar().bar); //returns bar

答案 3 :(得分:0)

在我可以之前,mwilson到了那里! ;)

在上面的代码中,Typescript无法确定对象x是否公开了一个名为bar的属性,因此在显示Intellisense时无法解析它。

相反,添加foobar等作为对象本身的属性:

var x = {
    foo: "FOO",
    bar: "BAR"
};

然后,当使用Typescript Playground时,您将看到Intellisense按预期工作:

enter image description here

HTH

答案 4 :(得分:0)

我个人更喜欢在有机会时指定类型。

请注意,如果您使用{}运算符将字段定义为可选字段,则只能使用?:实例化此变量。

let x: {foo?: string, bar?: string} = {};
x.foo = 'foo';
x.bar = 'bar';

正如其他人所说,如果你计划多次使用这种类型,最好为它做一个明确的类。

PS:在打字稿中编程时,最好使用let代替var。 (例如var声明的范围有点古怪,而let则与您期望它做的事情相同。)