TypeScript传播后丢失类型信息?

时间:2019-12-19 17:27:12

标签: typescript

在下面的代码中,为什么personInvalidAndErrorCaught分配给出TypeScript错误(正如我期望的那样),但是personInvalidButErrorUncaught没有给出错误?尤其是因为两行都转换为相同的JavaScript?

TypeScript:

interface Person {
    name: string;
}
const person: Person = { name: "name" }
const personInvalidAndErrorCaught: Person = { ...person, invalidKey: ""  } // Error as expected: Object literal may only specify known properties, and 'invalidKey' does not exist in type 'Person'.(2322)
const personInvalidButErrorUncaught: Person = { ...person, ...{ invalidKey: "" } } // Why no error? Especially since this line transpiles to the same JS as the line above?

已编译的JavaScript:

"use strict";
const person = { name: "name" };
const personInvalidButCaught = Object.assign(Object.assign({}, person), { invalidKey: "" }); 
const personInvalidButUncaught = Object.assign(Object.assign({}, person), { invalidKey: "" });

图片显示错误:

Screenshot of playground showing error

Playground Link

1 个答案:

答案 0 :(得分:1)

区别在于,在不起作用的情况下,您直接分配包含无效键的对象文字,而TypeScript会对其进行特殊处理。来自beta documentation (他们警告链接可能会腐烂)

  

请注意,createSquare的给定参数拼写为colour而不是color。在普通的JavaScript中,这种情况会自动失败。

     

您可能会认为该程序的类型正确,因为width属性兼容,没有color属性,并且多余的colour属性无关紧要。

     

但是,TypeScript认为此代码中可能存在错误。 对象文字在分配给其他变量或作为参数传递时会受到特殊对待,并进行过多的属性检查。

(我的重点)

(您还发现了current documentation。)

在第二种没有错误的情况下,您没有直接将具有多余属性的对象文字分配给变量,而是分配了将其传播到其中的包装对象。当然,这是一个微妙的区别,但这是一个区别。

这只是TypeScript的一个特殊情况,因为当您直接分配文字并指定无效的属性时,很可能是一个错误。可能没有更复杂的东西。

正如您在one of the tests中发现的那样,传播并不会触发此检查的事实是

const a1: A = { ...extra1 }; // spread should not give excess property errors
相关问题