Javascript 对对象的 TypeScript 和点符号访问

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30089879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:38:51  来源:igfitidea点击:

TypeScript and dot-notation access to objects

javascripttypescript

提问by user655321

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)的访问都会给我错误Property 'thing' does not exist on type '{}'.. 当我使用括号表示法(例如,myObj['thing'])时,它可以正常工作。

Property does not exist on type

类型上不存在属性

采纳答案by David Sherret

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 bardoes not exist on xbecause it has been implicitly typed to {}when writing var x = {};.

现在,正如编译器告诉您的那样,该属性bar不存在 onx因为它{}在编写var x = {};.

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

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

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

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

现在您可以 get 或 setx.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.

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

回答by Val

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 的实例。

回答by bvdb

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 letinstead of varwhen programming in typescript. (e.g. the scope of a vardeclaration is a bit quirky, compared to a letwhich does what you expect it to do.)

PS:在打字稿中编程时最好使用let而不是使用var。(例如var,与let执行您期望的操作的a 相比,声明的范围有点古怪。)

回答by mwilson

xdoes not hold any property named barso you need create it within the object:

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

function foobar() {
    var x = {

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

    return x;
}

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

回答by Rich Turner

mwilson got there before I could! ;)

姆威尔逊比我还来得及!;)

In the code above, Typescript is unable to determine that the object xexposes a property called barso cannot resolve it when displaying Intellisense.

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

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

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

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

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

然后,当使用Typescript Playground 时,您将看到 Intellisense 正常工作:

enter image description here

在此处输入图片说明

HTH

HTH