特殊对象类型
在 TypeScript 中,定义了几种特殊的对象类型——object
、Object
和 {}
,它们有相似的名字或概念,但又各有区别,接下来将分别介绍。注意,在实际使用时,只建议使用object
,Object
和 {}
不建议使用。
object
object
(首字母小写)类型是 TypeScript 新增的类型,用于表示非原始类型。在 TypeScript 中,原始类型有 number
、string
、boolean
、bigint
、symbol
。因此,object
类型表示除此以外的全部类型。
以下赋值代码会引起编译错误。
let a: object;
//编译错误:不能将类型"number"分配给类型"object"。ts(2322)
a = 1;
//编译错误:不能将类型"bigint"分配给类型"object"。ts(2322)
a = 1n;
//编译错误:不能将类型"boolean"分配给类型"object"。ts(2322)
a = true;
//编译错误:不能将类型"string"分配给类型"object"。ts(2322)
a = "";
//编译错误:不能将类型"symbol"分配给类型"object"。ts(2322)
a = Symbol();
以下为正确的赋值代码。
let a: object;
a = { name: "hello" };
a = [0, 1, 2, 3];
a = function () { console.log("hello") };
a = new Date(); //时间对象,它是一种内置对象,后面将详细介绍
注意,当对象为 object
类型时,因为 object
类型是一种泛指的类型,并不是具体的类型,因此无法得知它支持哪些属性或方法,需要将其转换为具体的类型才能操作。
let a: object = [1, 2, 3, 4];
let b: object = { name: "rex" };
let c: object = function () { console.log("hello world!") }
//以下使用方式将引起编译错误
//编译错误:类型"object"上不存在属性"length"。ts(2339)
console.log(a.length);
//编译错误:类型"object"上不存在属性"name"。ts(2339)
console.log(b.name);
//编译错误:此表达式不可调用。类型 "{}" 没有调用签名。ts(2349)
c();
//以下是正确的使用方式
console.log((a as number[]).length);
console.log((b as { name: string }).name);
(c as () => void)();
object
类型可用于参数传递过程中的处理。假设某函数要求能传入任意的非原始类型,则可以将其定义为 object
类型,而非 any
类型,示例代码如下。
function handleObject(obj: object) {
//...
}
Object和{}
Object
和 {}
类型都是 TypeScript 中不推荐使用的类型,这里只做简单介绍。这两种类型主要用于 JavaScript,TypeScript 中只保留了它们的功能。
Object
类型的字面意义是对象类型,{}
类型的字面意义是没有属性或方法的初始空对象类型,但它们不仅可以初始化为非原始类型,还可以初始化为原始类型。这是一个让人迷惑的设计,同时通常会引起误操作(这也是 TypeScript 中又引入 object
类型来表示非原始类型的原因)。示例代码如下。
let a: Object; //或者let a: {};
a = 1;
a = 1n;
a = true;
a = "";
a = Symbol();
a = { name: "hello" };
a = [0, 1, 2, 3];
a = function () { console.log("hello") };
a = new Date();
与 {}
类型相比,Object
类型还支持各种方法(如 Object.create()
、Object.setPrototypeOf()
方法等),这些方法通常用于原型和继承的处理,但在 TypeScript 中已经有比较完善的接口及类,它们可以处理继承关系,因此无须再使用这些落后的方式。感兴趣的读者可以自行研究。