TypeScript为何未限制类型别名遵循其定义的结构?
TypeScript为何未限制类型别名遵循其定义的结构?
兄弟,这其实是两个容易混淆的点在搞事情——const变量的不可变性和TypeScript结构类型系统的工作逻辑,我给你掰扯清楚:
先说说
const的作用:你用const声明newUser,只是限制了变量本身不能被重新赋值(比如不能写newUser = 别的对象),但它指向的对象/数组的内部属性是完全可以修改的!TypeScript和JavaScript里的const都管不了对象内部的变化,这是语言本身的设计,不是TypeScript的锅。再说说类型别名的结构限制:TypeScript是结构类型系统(鸭子类型),只要一个对象的结构和你定义的类型别名匹配,就会被认为符合该类型。但如果你的数组属性在类型里定义的是比如
boolean[],那push(true)本来就是符合类型要求的操作啊;要是你定义的是string[]却能push布尔值,那大概率是你的代码里数组的类型被隐式推断成any[]了,或者TypeScript的严格模式没开启(比如strictNullChecks、noImplicitAny这些配置没开),导致类型检查放松了。
举个实际的代码例子:
// 这种情况完全合法,不会报错 type User = { permissions: boolean[]; }; const newUser: User = { permissions: [] }; newUser.permissions.push(true);
// 这种情况TypeScript会直接报错,因为boolean不符合string[]的元素类型 type User = { permissions: string[]; }; const newUser: User = { permissions: [] }; newUser.permissions.push(true);
总结一下:核心是const只限制变量的引用不可变,不限制对象内部的修改;而类型别名的结构限制只会检查你操作的元素类型是否匹配数组的定义。如果你的情况是明明元素类型不匹配却没报错,去检查下你的TypeScript配置,大概率是严格模式没开启导致类型检查不够严格。
备注:内容来源于stack exchange,提问作者Radical Rosh
相关产品推荐
相关产品推荐

