这里是TypeScript新手,我目前正在TutorialsPoint here上学习该语言。 我目前很难理解这两段代码之间的差异。
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
两者有什么区别?是否存在使用第一个/第二个实施更好的特定情况?
谢谢。
答案 0 :(得分:0)
这些例子略有不同:
Musician
的变量,然后将一个对象分配给适合该类型的变量。Musicican
。
{} as Musician
- 您使用的尖括号语法与React应用程序常用的JSX语法扩展不兼容,因此它被替换为某些东西不那么暧昧。我会在绝大多数情况下推荐第一个例子 - 空对象并没有真正实现Musician
,所以你有效地回避那里的类型检查器!
您可以使用第二种方法设置案例的一种情况是,如果您的Musician
开始为空并且稍后会填充 - 在这种情况下,我认为您会更好通过使字段可选来通过类型定义本身进行建模:
interface Person {
// '?' makes a field optional
age?: number;
}
interface Musician extends Person {
instrument?: string;
}
// The cast can now be replaced with a proper type
var drummer: Musician = {};
drummer.instrument = "drum";
drummer.age = 28;
这使得(对于您,其他开发人员和编译器)更加清楚,在某些情况下,这些字段将是未定义的。
答案 1 :(得分:0)
它们最终相同,但前者在可能的情况下是首选。
在这种情况下:
var drummer: Musician = {
instrument: "drum",
age: 28
}
您通过使用type annotation声明drummer
为Musician
,并为其指定了一个对象字面值。编译器对此感到高兴,因为它可以验证是,您分配的对象文字与Musician
接口兼容。它具有字符串值instrument
属性和数值age
属性。
现在如果我们尝试这个怎么办:
var drummer: Musician = {};
// ~~~~~~~ <-- error!
// Type '{}' is not assignable to type 'Musician'.
// Property 'instrument' is missing in type '{}'.
drummer.instrument = "drum"
drummer.age = 28
将空对象文字赋值为声明为Musician
的值会导致编译器错误。毕竟,空对象文字没有字符串值instrument
属性或数值age
属性。而且你被警告了。现在,你知道接下来的两行将解决这个问题,但编译器没有。
因此,您可以将其更改为使用type assertion而不是类型注释:
var drummer = <Musician>{}; // okay
drummer.instrument = "drum"
drummer.age = 28
断言是你告诉编译器“这个对象真的是Musician
的地方,即使它现在看起来不像它。”您承担的责任是确保drummer
是Musician
,并使编译者免除为您验证的责任。
由于接下来的两行添加了所需的属性,一切都很好。
前者是首选,因为您通常希望编译器验证您的类型。一种类型的断言放弃了一些安全性,这种情况很好,直到没有安全带,就像驾驶没有安全带的汽车一样:
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
对象没有所需flex-growth
的短时间。因此需要断言。
这有意义吗?希望能帮助到你;祝你好运!