为什么在Typescript 的对象中要慎用扩展运算符(三个点...)

先说结论:

在 Typescript 的对象中使用扩展运算符(三个点...),有很大可能会使整个对象的类型检查失效。

示例代码

type BirdBasicType = {
  wings: number;
  name: string;
};
type eyePropsType = { eyeInfo: { color: string; open: boolean };};
type Owl = eyePropsType & BirdBasicType;

const basicOwl: BirdBasicType = { wings: 2, name: 'peter'};

const abc: any = { hhh: 45, nnn: 'vnoe'}

const owl: Owl = { ...basicOwl,  eyeInfo: { color: 12, open: true, amount: 21, legs: 12, ...(abc && {hhh: abc.hhh, nnn: abc.nnn})}  };

我们发现虽然 ts 知道 eyeInfo 的类型,但是没有对 color 的类型错误做出任何提示(应该是 string,实际却是 number).

修改一下,把扩展运算符(三个点...)删除,ts 可以检查类型了:(至于多出来的两个字段,需要先把 color 改对才会显示他们的错误)

总结

这里我们显示地定义了一个 any 类型的对象 abc,然而生产环境的代码往往类型十分隐蔽,如果使用扩展运算符(三个点...)在对象中展开一个 any类型的对象,那么即使有类型声明,也检查不出错误。
这是 TypeScript 的bug 吗? 不算是,具体参考此issue: https://github.com/microsoft/TypeScript/issues/47995
Playground: 分别使用 typeinterface 定义对象,以及他们的区别: link

posted @ 2023-02-08 21:51  略略略——  阅读(546)  评论(0编辑  收藏  举报