【问题标题】:Types and names should match类型和名称应匹配
【发布时间】: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


【解决方案1】:

编辑 2

type Point = { x: number, y: string};
type Vector2 = { 0: number, 1: string}
let p :Point;
let v :Vector2 = p;

同样这里也有两种选择。

  1. 由于类型不兼容而引发错误。
  2. 将值转换为适当的字段,这样我们就不必做一些额外的事情了。

选项 1 具有最高优先级。正如@binDebug 所提到的,这就是构建这种语言的原因。

编辑

typescript 转成 js 后的样子

function keepWholeObject(obj_param){
    let {a, b} = obj_param;
    console.log(`In function - ${a}`);
    console.log(`In function - ${b}`);
} 

没有任何类型信息。

上一个答案

function keepWholeObject(obj_param: { a: string, b: number }) {
  let { a, b }: { a: string, b: number } = obj_param;
  console.log(`In function - ${a}`);
  console.log(`In function - ${b}`);
}
  1. obj_param: { a: string, b: number } 不适用于 xy
  2. 类型是编译时特性,在运行时被擦除。
  3. 解构是一种 JavaScript 功能。总结一下 javascript 解构的工作原理。

【讨论】:

  • 请再读一遍问题.. JS 中的代码对我来说是一个抽象.. 使用 TypeScript 后
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 2013-01-20
  • 1970-01-01
相关资源
最近更新 更多