谈谈{}跟Object以及object的区别

在TS中,相信很多人搞不清Objectobject以及{}之间的关系,或者没有深究过,觉得他们只是同一个类型的不同别名,其实不然,每一个的存在都是有原因的。今天我们一起来探究他们的不同之处。

{}

{}包含了除了nullundefined所有的类型,类似于这样:

(这也是{}unknown的区别,unknown可以包含nullundefined)

但是它对它所指向的对象一无所知,访问任何属性或者方法都会报找不到:

{}就像一个大集合,包含了其他的类型。

其实整个类型系统都是如此,类型表示值的集合。在我们日常coding过程中,时不时会遇到Argument of type 'xxx' is not assignable to parameter of type 'xxx'.的报错,其实就是看我们要赋的值在不在我们声明的对象的集合里面。(比如"foo"|"bar"这种literal type可以赋给接受string类型的变量)。

Object

类似于{},所有拥有Object原型的值都能赋给Object作为类型的变量。

但是有一丢丢规则,值的原型里得有Object(当然了,JS的大部分值都是有的)。

它所指向的对象一无所知,访问任何属性或者方法都会报找不到:

需要注意,Object对于对象里的某些方法是有要求的(比如Object原型对象的toString方法):

这里Object就不能用了,而{}没有这种检查。这种行为有时候让人迷惑,所以二者选其一,我选{},😁

object

然后就是object类型了。 object{}有一点不同,它不包含原始类型。

除了这一点,其它的跟{}很相似。

所以我们应该用哪个呢?

一般情况下,我们应该一个也不用😝。如果我们知道我们数据的具体结构,那单独创建一个type或者interface是最好的。但是在类型编程的时候,我们就得选一个。

比如我们有一个merge函数,用来合并两个对象,把我们可能会这么写:

typescript 复制代码
function merge<A extends {},B extends {}>(a:A,b:B):A&B{
    return {
        ...a,
        ...b
    }
}

或者这样:

typescript 复制代码
function merge<A extends Object,B extends Object>(a:A,b:B):A&B{
    return {
        ...a,
        ...b
    }
}

看起来没问题,但我们传给它原始类型它是可以接受的,结果似乎有点奇怪:

这大概不是我们写merge函数想要的效果。如果这时候我们把类型参数换成object,问题就迎刃而解了。

所以:

  1. 用于一些复合对象的情况,选object
  2. 复合对象跟原始类型皆可的情况,选{}
  3. 如果要包含nullundefined的情况,用unknown
相关推荐
程序视点29 分钟前
2023最新HitPaw免注册版下载:一键去除图片视频水印的终极教程
前端
小只笨笨狗~2 小时前
el-dialog宽度根据内容撑开
前端·vue.js·elementui
weixin_490354342 小时前
Vue设计与实现
前端·javascript·vue.js
GISer_Jing3 小时前
React过渡更新:优化渲染性能的秘密
javascript·react.js·ecmascript
烛阴3 小时前
带你用TS彻底搞懂ECS架构模式
前端·javascript·typescript
wayhome在哪3 小时前
3 分钟上手!用 WebAssembly 优化前端图片处理性能(附完整代码)
javascript·性能优化·webassembly
卓码软件测评4 小时前
【第三方网站运行环境测试:服务器配置(如Nginx/Apache)的WEB安全测试重点】
运维·服务器·前端·网络协议·nginx·web安全·apache
龙在天4 小时前
前端不求人系列 之 一条命令自动部署项目
前端
开开心心就好4 小时前
PDF转长图工具,一键多页转图片
java·服务器·前端·数据库·人工智能·pdf·推荐算法
国家不保护废物4 小时前
10万条数据插入页面:从性能优化到虚拟列表的终极方案
前端·面试·性能优化