TypeScript和点符号访问对象

时间:2022-10-20 22:30:02

If TypeScript is a strict superset of JavaScript, why is dot notation on an arbitrary object erroneous? I have JS code that I want to convert over to TS for better type safety, but all access using dot notation (eg, myObj.thing) gives me the error Property 'thing' does not exist on type '{}'.. It works properly when I use bracket notation (eg, myObj['thing']).

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

TypeScript和点符号访问对象

5 个解决方案

#1


I know you say this is odd, but this is one of the main reasons TypeScript exists. This error helps prevent accidentally setting or getting non-existent properties on an object.

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

Right now, as the compiler is telling you, the property bar does not exist on x because it has been implicitly typed to {} when writing var x = {};.

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

You can tell the compiler that x has more than zero properties by explicitly defining the type:

您可以通过显式定义类型告诉编译器x具有多于零的属性:

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

Now you can get or set x.foo and x.bar without the compiler complaining. In most cases, you would move this into an interface like so:

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

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

var x: IFooBar = {};

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

Some people are recommending you cast to any, but don't get lazy. You should make full use of the type system TypeScript provides. Doing so will most definitely save you time down the road as you maintain an application.

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

#2


Because of the strongly-typed nature of Typescript Object, you can use "any" to make it untyped:

由于Typescript对象的强类型性质,您可以使用“any”使其无类型化:

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

If what's you need is to define type of literal properties

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

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

then x["bar"] can now only be instance of TypeA.

那么x [“bar”]现在只能是TypeA的实例。

#3


x does not hold any property named bar so you need create it within the object:

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

function foobar() {
    var x = {

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

    return x;
}

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

#4


mwilson got there before I could! ;)

我可以在那之前到达那里! ;)

In the code above, Typescript is unable to determine that the object x exposes a property called bar so cannot resolve it when displaying Intellisense.

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

Instead, add foo, bar, etc. as properties of the object itself:

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

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

Then, when using the Typescript Playground, you'll be see the Intellisense work as expected:

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

TypeScript和点符号访问对象

HTH

#5


I personally prefer to specify types whenever I have the chance.

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

Note, that you can only instantiate this variable with {} if you define the fields as optional with the ?: operator.

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

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

As others have said, if you plan to use this type multiple times, it's probably better to make an explicit class for it.

正如其他人所说,如果你打算多次使用这种类型,那么为它做一个明确的类可能会更好。

PS: it's better to use let instead of var when programming in typescript. (e.g. the scope of a var declaration is a bit quirky, compared to a let which does what you expect it to do.)

PS:在打字稿中编程时最好使用let而不是var。 (例如var声明的范围有点古怪,相比于let你做的预期。)

#1


I know you say this is odd, but this is one of the main reasons TypeScript exists. This error helps prevent accidentally setting or getting non-existent properties on an object.

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

Right now, as the compiler is telling you, the property bar does not exist on x because it has been implicitly typed to {} when writing var x = {};.

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

You can tell the compiler that x has more than zero properties by explicitly defining the type:

您可以通过显式定义类型告诉编译器x具有多于零的属性:

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

Now you can get or set x.foo and x.bar without the compiler complaining. In most cases, you would move this into an interface like so:

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

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

var x: IFooBar = {};

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

Some people are recommending you cast to any, but don't get lazy. You should make full use of the type system TypeScript provides. Doing so will most definitely save you time down the road as you maintain an application.

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

#2


Because of the strongly-typed nature of Typescript Object, you can use "any" to make it untyped:

由于Typescript对象的强类型性质,您可以使用“any”使其无类型化:

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

If what's you need is to define type of literal properties

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

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

then x["bar"] can now only be instance of TypeA.

那么x [“bar”]现在只能是TypeA的实例。

#3


x does not hold any property named bar so you need create it within the object:

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

function foobar() {
    var x = {

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

    return x;
}

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

#4


mwilson got there before I could! ;)

我可以在那之前到达那里! ;)

In the code above, Typescript is unable to determine that the object x exposes a property called bar so cannot resolve it when displaying Intellisense.

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

Instead, add foo, bar, etc. as properties of the object itself:

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

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

Then, when using the Typescript Playground, you'll be see the Intellisense work as expected:

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

TypeScript和点符号访问对象

HTH

#5


I personally prefer to specify types whenever I have the chance.

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

Note, that you can only instantiate this variable with {} if you define the fields as optional with the ?: operator.

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

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

As others have said, if you plan to use this type multiple times, it's probably better to make an explicit class for it.

正如其他人所说,如果你打算多次使用这种类型,那么为它做一个明确的类可能会更好。

PS: it's better to use let instead of var when programming in typescript. (e.g. the scope of a var declaration is a bit quirky, compared to a let which does what you expect it to do.)

PS:在打字稿中编程时最好使用let而不是var。 (例如var声明的范围有点古怪,相比于let你做的预期。)

相关文章