【发布时间】:2018-10-07 10:59:58
【问题描述】:
对于t类型的给定命名对象,
interface t {
a: string,
b: number,
c: string
}
let obj:t = {
a: "foo",
b: 12,
c: "bar"
}
下面是处理这个命名对象的函数,
function keepWholeObject(obj_param: {x: string, y:number}){
let {a, b}:{a: string, b: number} = obj_param;
console.log(`In function - ${a}`);
console.log(`In function - ${b}`);
}
在哪里
let {a, b}:{a: string, b: number} = obj_param; 不起作用。
因为,类型和名称应该匹配。错误是:Type '{ x: string; y: number; }' is not assignable to type '{ a: string; b: number; }'. Property 'a' is missing in type '{ x: string; y: number; }'
结构类型与主格类型的一个缺陷是,两个单独定义的类型用于不同的目的,但意外地拥有相同的属性(例如,两者都由一对整数),可以被类型系统认为是相同的类型,仅仅是因为它们恰好具有相同的结构。避免这种情况的一种方法是为每次使用创建一个代数数据类型(复合类型)。 taken from
这就是为什么在上面的函数声明中,我使用解构为 obj_param: {a: string, b:number} 而不是 {a, b}: {a: string, b:number} 的复合类型声明参数以避免重复标识符。匹配名称和类型的副作用。
为什么 TypeScript 不允许分配具有相同类型的对象?结构类型?
【问题讨论】:
-
这不是类型安全的重点吗?如果属性(名称)不同,则对象不同。所以不能赋值对吧?
-
@binDebug 匹配类型(内存结构)不足以保证类型安全?
-
类型安全,顾名思义,就是匹配设计类型。理论上,一个人可以有数字(年龄)和字符串(姓名),而汽车可以有数字(价格)和字符串(姓名)。一个不能分配给另一个,对吧?
-
@binDebug wiki 中定义的结构类型系统:如果对于第二个元素类型中的每个特征,第一个元素的类型中存在对应且相同的特征,则认为一个元素与另一个元素兼容类型。 某些语言可能在细节上有所不同,例如功能是否名称必须匹配。此定义不对称,并且包括子类型兼容性。如果两种类型相互兼容,则认为两种类型是相同的。我认为,就类型等效性而言,GO 与 TypeScript 是一致的。
-
@overexchange 但是
{a, b}和{x, y}没有 有匹配的内存结构?这正是编译器错误告诉你的。对象不是元组,它们是记录。
标签: javascript typescript ecmascript-6 strong-typing