【发布时间】:2013-09-28 11:09:03
【问题描述】:
我正在查看 TypeScript 代码并注意到它们使用:
interface Blablabla {
field: Object;
}
使用Object 与any 有什么好处,如:
interface Blablabla {
field: any;
}
【问题讨论】:
标签: typescript
我正在查看 TypeScript 代码并注意到它们使用:
interface Blablabla {
field: Object;
}
使用Object 与any 有什么好处,如:
interface Blablabla {
field: any;
}
【问题讨论】:
标签: typescript
Object 似乎是比任何声明都更具体的声明。来自 TypeScript 规范(第 3 节):
TypeScript 中的所有类型都是单一顶级类型的子类型,称为 任意种类。 any 关键字引用此类型。 Any 类型是 一种可以无约束地表示任何 JavaScript 值的类型。 所有其他类型都归类为原始类型、对象类型或 类型参数。这些类型引入了各种静态约束 他们的价值观。
还有:
Any 类型用于表示任何 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'.
【讨论】:
Object 比 any 更严格。例如:
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 类中定义的函数和属性。【讨论】:
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;
【讨论】:
Object 和 object。
Object和object在TS中的区别吗?
object 是所有非原始类型的类型,而Object 是一个包含toString 等常见事物的接口。数字 42 将是 Object,但不是 object。
与所有类型都派生自“对象”的 .NET 相反,在 TypeScript 中,所有类型都派生自“任何”。我只是想添加这个比较,因为我认为随着越来越多的 .NET 开发人员尝试 TypeScript,这将是一个常见的比较。
【讨论】:
有点旧,但添加一些注释也无妨。
当你写这样的东西时
let a: any;
let b: Object;
let c: {};
这就是为什么
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 应该接受多个已知类型,更好的方法是使用联合类型声明它,如
function fc(param: string|number): void {}
显然,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,超出了范围,我只是想澄清 any 应该只在你不知道会发生什么时使用,而对于其他任何事情你应该注释正确的类型。
更新:
Typescript 2.2 添加了一个object 类型,它指定一个值是非原始的:(即不是number、string、boolean、symbol、undefined 或@ 987654336@).
考虑定义为的函数:
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
【讨论】:
{},然后如果他们已经有Object? (反之亦然,以先到者为准)肯定有一些细微差别,对吧?
{} 是定义(内联)接口的常规方法,只是在这种情况下,您定义的是没有成员的接口。细微的差别在响应中得到了很好的解释:“{} 扩展了Object,就像 TypeScript 中的其他任何东西一样”。
any 并进行运行时类型检查。不要使用any,而是使用您要检查的类型的联合:TypeA|InterfaceB|string。如果您还有未知类型的默认情况,请将{} 或Object 添加到联合中。
But variables of type Object only allow you to assign any value to them - you can’t call arbitrary methods on them, even ones that actually exist: 让我认为即使调用 toString 也是不允许的,而实际上我认为他们在阅读您的答案后想说 exist at runtime。
添加到亚历克斯的答案并简化它:
对象对它们的使用更加严格,因此给程序员更多的编译时间“评估”能力,因此在很多情况下提供更多的“检查能力”并可以防止任何泄漏,而任何是一个更通用的术语和因此可能会忽略大量编译时检查。
【讨论】: