typescript “任何”与“对象”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18961203/
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-09-11 01:09:13  来源:igfitidea点击:

'any' vs 'Object'

typescript

提问by Olivier Refalo

I am looking at TypeScript code and noticed that they use:

我正在查看 TypeScript 代码并注意到它们使用:

interface Blablabla {

   field: Object;

}

What is the benefit of using Objectvs any, as in:

使用Objectvs 有什么好处any,例如:

interface Blablabla {

  field: any;

}

采纳答案by Nypan

Objectis more restrictive than any. For example:

Object比 更严格any。例如:

let a: any;
let b: Object;

a.nomethod(); // Transpiles just fine
b.nomethod(); // Error: Property 'nomethod' does not exist on type 'Object'.

The Objectclass does not have a nomethod()function, therefore the transpiler will generate an error telling you exactly that. If you use anyinstead you are basically telling the transpiler that anything goes, you are providing no information about what is stored in a- it can be anything! And therefore the transpiler will allow you to do whatever you want with something defined as any.

Object类不具有nomethod()的功能,因此transpiler将产生一个错误,告诉你这一点。如果您any改为使用,您基本上是在告诉转译器一切正常,您没有提供有关存储内容的信息a- 它可以是任何东西!因此,转译器将允许您使用定义为any.

So in short

所以简而言之

  • anycan be anything (you can call any method etc on it without compilation errors)
  • Objectexposes the functions and properties defined in the Objectclass.
  • any可以是任何东西(您可以在其上调用任何方法等而不会出现编译错误)
  • Object公开Object类中定义的函数和属性。

回答by diegovilar

Bit old, but doesn't hurt to add some notes.

有点旧,但添加一些注释也无妨。

When you write something like this

当你写这样的东西时

let a: any;
let b: Object;
let c: {};
  • ahas no interface, it can be anything, the compiler knows nothing about its members so no type checking is performed when accessing/assigning both to it and its members. Basically, you're telling the compiler to "back off, I know what I'm doing, so just trust me";
  • bhas the Object interface, so ONLY the members defined in that interface are available for b. It's still JavaScript, so everything extends Object;
  • cextends Object, like anything else in TypeScript, but adds no members. Since type compatibility in TypeScript is based on structural subtyping, not nominal subtyping, cends up being the same as bbecause they have the same interface: the Object interface.
  • a没有接口,它可以是任何东西,编译器对其成员一无所知,因此在访问/分配给它及其成员时不执行类型检查。基本上,您是在告诉编译器“退后,我知道我在做什么,所以请相信我”;
  • b具有 Object 接口,因此只有在该接口中定义的成员才可用于b。它仍然是 JavaScript,所以一切都扩展了 Object;
  • c扩展 Object,就像 TypeScript 中的其他任何东西一样,但不添加任何成员。由于 TypeScript 中的类型兼容性基于结构子类型,而不是名义子类型,因此c最终与b相同,因为它们具有相同的接口:Object 接口。

And that's why

这就是为什么

a.doSomething(); // Ok: the compiler trusts you on that
b.doSomething(); // Error: Object has no doSomething member
c.doSomething(); // Error: c neither has doSomething nor inherits it from Object

and why

为什么

a.toString(); // Ok: whatever, dude, have it your way
b.toString(); // Ok: toString is defined in Object
c.toString(); // Ok: c inherits toString from Object

So Objectand {}are equivalents in TypeScript.

所以Object{}是 TypeScript 中的等价物。

If you declare functions like these

如果你声明这样的函数

function fa(param: any): void {}
function fb(param: Object): void {}

with the intention of accepting anything for param (maybe you're going to check types at run-time to decide what to do with it), remember that

为了接受 param 的任何内容(也许您将在运行时检查类型以决定如何处理它),请记住

  • inside fa, the compiler will let you do whatever you want with param;
  • inside fb, the compiler will only let you reference Object's members.
  • fa里面,编译器会让你用param做任何你想做的事情;
  • fb 中,编译器只会让你引用Object的成员。

It is worth noting, though, that if paramis supposed to accept multiple known types, a better approach is to declare it using union types, as in

不过值得注意的是,如果param应该接受多个已知类型,更好的方法是使用联合类型声明它,如

function fc(param: string|number): void {}

Obviously, OO inheritance rules still apply, so if you want to accept instances of derived classes and treat them based on their base type, as in

显然,OO 继承规则仍然适用,所以如果你想接受派生类的实例并根据它们的基类型来对待它们,如

interface IPerson {
    gender: string;
}

class Person implements IPerson {
    gender: string;
}

class Teacher extends Person {}

function func(person: IPerson): void {
    console.log(person.gender);
}

func(new Person());     // Ok
func(new Teacher());    // Ok
func({gender: 'male'}); // Ok
func({name: 'male'});   // Error: no gender..

the base type is the way to do it, not any. But that's OO, out of scope, I just wanted to clarify that anyshould only be used when you don't know whats coming, and for anything else you should annotate the correct type.

基本类型是这样做的方法,而不是任何. 但那是 OO,超出范围,我只是想澄清any只应在您不知道即将发生什么时使用,对于其他任何事情,您都应该注释正确的类型。

UPDATE:

更新:

Typescript 2.2added an objecttype, which specifies that a value is a non-primitive: (i.e. not a number, string, boolean, symbol, undefined, or null).

Typescript 2.2添加了一个object类型,它指定一个值是非原始的:(即不是 a number, string, boolean, symbol, undefined, or null)。

Consider functions defined as:

考虑定义为的函数:

function b(x: Object) {}
function c(x: {}) {}
function d(x: object) {}

xwill have the same available properties within all of these functions, but it's a type error to call dwith a primitive:

x在所有这些函数中将具有相同的可用属性,但d使用原语调用会导致类型错误:

b("foo"); //Okay
c("foo"); //Okay
d("foo"); //Error: "foo" is a primitive

回答by basarat

anyis something specific to TypeScript is explained quite well by alex's answer.

any亚历克斯的回答很好地解释了 TypeScript 特有的东西。

Objectrefers to the JavaScript objecttype. Commonly used as {}or sometimes new Object. Most things in javascriptare compatible with the object data type as they inherit from it. But anyis TypeScriptspecific and compatible with everything in both directions (not inheritance based). e.g. :

Object指的是 JavaScriptobject类型。常用作{}或有时new Objectjavascript中的大多数东西都与对象数据类型兼容,因为它们是从它继承而来的。但是TypeScriptany是特定的并且与两个方向的所有内容兼容(不是基于继承的)。例如:

var foo:Object; 
var bar:any;
var num:number;

foo = num; // Not an error
num = foo; // ERROR 

// Any is compatible both ways 
bar = num;
num = bar;  

回答by yellowbrickcode

Contrary to .NET where all types derive from an "object", in TypeScript, all types derive from "any". I just wanted to add this comparison as I think it will be a common one made as more .NET developers give TypeScript a try.

与所有类型都源自“对象”的 .NET 相反,在 TypeScript 中,所有类型都源自“任何”。我只是想添加这个比较,因为我认为随着越来越多的 .NET 开发人员尝试使用 TypeScript,这将是一个常见的比较。

回答by Alex Dresko

Object appears to be a more specific declaration than any. From the TypeScript spec (section 3):

Object 似乎是一个比任何声明都更具体的声明。来自 TypeScript 规范(第 3 节):

All types in TypeScript are subtypes of a single top type called the Any type. The any keyword references this type. The Any type is the one type that can represent any JavaScript value with no constraints. All other types are categorized as primitive types, object types, or type parameters. These types introduce various static constraints on their values.

TypeScript 中的所有类型都是称为 Any 类型的单一顶级类型的子类型。any 关键字引用此类型。Any 类型是一种可以无约束地表示任何 JavaScript 值的类型。所有其他类型都归类为原始类型、对象类型或类型参数。这些类型对其值引入了各种静态约束。

Also:

还:

The Any type is used to represent any JavaScript value. A value of the Any type supports the same operations as a value in JavaScript and minimal static type checking is performed for operations on Any values. Specifically, properties of any name can be accessed through an Any value and Any values can be called as functions or constructors with any argument list.

Any 类型用于表示任何 JavaScript 值。Any 类型的值支持与 JavaScript 中的值相同的操作,并且对 Any 值的操作执行最少的静态类型检查。具体来说,任何名称的属性都可以通过 Any 值访问,并且 Any 值可以作为具有任何参数列表的函数或构造函数调用。

Objects do not allow the same flexibility.

对象不允许具有相同的灵活性。

For example:

例如:

var myAny : any;

myAny.Something(); // no problemo

var myObject : Object;

myObject.Something(); // Error: The property 'Something' does not exist on value of type 'Object'.

回答by Krishna Ganeriwal

Adding to Alex's answer and simplifying it:

添加到亚历克斯的答案并简化它:

Objects are more strict with their use and hence gives the programmer more compile time "evaluation" power and hence in a lot of cases provide more "checking capability" and coould prevent any leaks, whereas any is a more generic term and a lot of compile time checks might hence be ignored.

对象对它们的使用更加严格,因此赋予程序员更多的编译时间“评估”能力,因此在很多情况下提供更多的“检查能力”并可以防止任何泄漏,而 any 是一个更通用的术语和大量编译因此,时间检查可能会被忽略。