'any'vs'Object'

时间:2013-09-23 13:58:58

标签: typescript

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

interface Blablabla {

   field: Object;

}

使用Object vs any有什么好处,如:

interface Blablabla {

  field: any;

}

8 个答案:

答案 0 :(得分:222)

有点旧,但添加一些音符并不会有什么坏处。

当你写这样的东西时

var a: any;
var b: Object;
var c: {};
  • a 没有接口,它可以是任何东西,编译器对其成员一无所知,因此在访问/分配自身及其成员时完成最小类型检查。基本上,你告诉编译器" 退出,我知道我在做什么,所以请相信我";
  • b 具有Object界面,因此只有该界面中定义的成员可用于 b 。它仍然是JavaScript,因此所有内容都扩展了Object;
  • c 扩展Object,与TypeScript中的任何其他内容一样,但不添加任何成员。由于TypeScript中的类型兼容性基于结构子类型,而不是名义上的子类型, c 最终与 b 相同,因为它们具有相同的接口:Object接口。

这就是为什么

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

以及为什么

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

因此,Object{}对于TypeScript都是等效的。我没有看到任何人真正使用它。太过限制了。

如果宣布这些功能

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

打算接受param的任何内容(也许你会在运行时检查类型以决定如何处理它),请记住

  • fa 内,编译器会让你用 param ;
  • 做任何你想做的事情
  • fb 内,编译器只允许您访问对象的成员,并且您最终不得不在那里进行大量的类型转换...

因此,基本上,当您不知道类型时,请使用任意进行运行时类型检查。

显然,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..

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

更新:

Typescript 2.2添加了object类型,指定值是非原始的:(即不是numberstringbooleansymbolundefinednull)。

考虑定义为:

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

x在所有这些函数中都具有相同的可用属性,但使用任何非原始函数调用d都是类型错误:

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

答案 1 :(得分:162)

Objectany更具限制性。例如:

let a: any;
let b: Object;

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

Object类没有nomethod()函数,因此转换器会生成错误,告诉您确切的错误。如果您使用any而不是基本上告诉转换器任何事情,那么您不会提供有关a中存储内容的信息 - 它可以是任何内容!因此,转换器将允许您使用定义为any的内容执行任何操作。

所以简而言之

  • any可以是任何东西(你可以在没有编译错误的情况下调用任何方法等)
  • Object公开Object类中定义的函数和属性。

答案 2 :(得分:23)

any是特定于TypeScript的东西,由alex的答案解释得很好。

Object指的是JavaScript object类型。通常用作{}或有时new Object javascript 中的大多数内容与从中继承的对象数据类型兼容。但是any TypeScript 是特定的,并且与两个方向上的所有内容兼容(不基于继承)。例如:

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;  

答案 3 :(得分:15)

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

答案 4 :(得分:13)

对象似乎是一个比任何更具体的声明。从TypeScript规范(第3节):

  

TypeScript中的所有类型都是单个顶级类型的子类型,称为   随便哪种。 any关键字引用此类型。 Any类型是   一种类型,可以表示没有约束的任何JavaScript值。   所有其他类型分类为基本类型,对象类型或   类型参数。这些类型引入了各种静态约束   他们的价值观。

此外:

  

Any类型用于表示任何JavaScript值。一个值   任何类型都支持与JavaScript和JavaScript中的值相同的操作   对Any上的操作执行最小静态类型检查   值。具体而言,可以访问任何名称的属性   任何值和任何值都可以作为函数或调用   带有任何参数列表的构造函数。

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

例如:

var myAny : any;

myAny.Something(); // no problemo

var myObject : Object;

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

答案 5 :(得分:0)

添加Alex的答案并简化它:

对象的使用更严格,因此给程序员更多的编译时间和评估"电源,因此在很多情况下提供更多的检查能力"并且可以防止任何泄漏,而任何都是更通用的术语,因此可能会忽略许多编译时间检查。

答案 6 :(得分:0)

请记住,您切勿相应地使用类型 Number String Boolean Object 到Typescript文档

  

这些类型是指非原始的盒装对象,这些对象几乎从未在JavaScript代码中正确使用。

答案 7 :(得分:-2)

试试这个:

String(array, boolean)