首页 > 解决方案 > Typescript 自定义接口变量声明

问题描述

TypeScript 新手在这里,我目前正在这里学习 TutorialsPoint的语言。我目前很难理解这两段代码之间的区别。

interface Person{
    age: number;
}

interface Musician extends Person{
    instrument: string;
}

var drummer:Musician = {
    instrument: "drum",
    age: 28
}

interface Person{
    age: number;
}

interface Musician extends Person{
    instrument: string;
}

var drummer = <Musician>{}
drummer.instrument = "drum"
drummer.age = 28

两者有什么区别?是否存在使用第一个/第二个实现更好的特定情况?

谢谢你。

标签: angulartypescriptdeclaration

解决方案


它们最终等同于同一件事,但如果可能,前者是首选。

在这种情况下:

var drummer: Musician = {
    instrument: "drum",
    age: 28
}

您通过使用类型注释drummer来声明它,并为其分配一个对象文字。编译器对此很满意,因为它可以验证是的,您分配的对象文字与接口兼容。它有一个字符串值属性和一个数值属性。 MusicianMusicianinstrumentage

现在如果我们试试这个:

var drummer: Musician = {};
//  ~~~~~~~ <-- error!
// Type '{}' is not assignable to type 'Musician'.
//  Property 'instrument' is missing in type '{}'.
drummer.instrument = "drum"
drummer.age = 28

将空对象文字分配给声明为 a 的值Musician会导致编译器错误。毕竟,空对象文字没有字符串值instrument属性或数值age属性。你被警告了。现在,知道接下来的两行将解决该问题,但编译器没有。

因此,您可以将其更改为使用类型断言而不是类型注释:

var drummer = <Musician>{}; // okay
drummer.instrument = "drum"
drummer.age = 28

断言是你告诉编译器“这个对象实际上是一个Musician,即使现在它看起来不像它。” 您负责确保这drummer是 aMusician并减轻编译器为您验证的责任。

而且由于接下来的两行添加了所需的属性,所以一切都很好。


前者更可取,因为您通常希望编译器能够验证您的类型。类型断言放弃了一些安全性,这很好,直到它不是,就像在没有安全带的情况下驾驶汽车:

var drummer = <Musician>{}; // okay
drummer.age = 28;
// whoops, forgot the instrument, but TypeScript isn't complaining

// ... later ...
console.log(drummer.instrument.toUpperCase()); 
// no error at compile time
// but blows up at runtime

有时您必须使用类型断言。例如,当您有某种循环引用需要分段构建对象时:

interface MarriedPerson extends Person {
  spouse: MarriedPerson
}

var adam: MarriedPerson = {
  age: 0,
  // spouse: eve <-- can't do this before eve is defined
} as MarriedPerson;

var eve: MarriedPerson = {
  age: 0,
  spouse: adam
}

adam.spouse = eve;  // okay now

在上面,每个都MarriedPerson需要一个对MarriedPerson... 的引用,但在你创建一个之前不会有一个。MarriedPerson因此,您不得不求助于其中一个对象没有所需的短时间内spouse。因此需要断言。

那有意义吗?希望能帮助到你; 祝你好运!


推荐阅读