在vanilla JavaScript中,设置类的原型字段很容易:
class Bird {
static {
this.prototype.canFly = true;
}
}
new Bird().canFly // true
然而,在TypeScript中,编译器会抱怨该属性不存在,我们可以用@ts-ignore
标记错误行,这样就可以工作,但这样我们就失去了对该字段的智能感知和类型检查。
此外,我们不能显式声明class字段,因为这样我们就需要初始化该字段,这就违背了建立原型的目的。
class Bird {
canFly: boolean; // Property 'canFly' has no initializer and is not definitely assigned in the constructor.ts(2564)
static {
this.prototype.canFly = true;
}
}
即使我们对它进行@ts-ignore
,该字段仍然使用undefined
进行初始化,只是为了显式声明。
class Bird {
// @ts-ignore
canFly: boolean;
static {
this.prototype.canFly = true;
}
}
new Bird().canFly; // undefined
我也尝试过使用declare
关键字"外部"声明字段,但也是不可能的:
class Bird { // Duplicate identifier 'Bird'.ts(2300)
static {
this.prototype.canFly = true;
}
}
declare class Bird { // Duplicate identifier 'Bird'.ts(2300)
canFly: boolean;
}
有没有一种TypeScript方法可以声明字段存在,而不必在示例中初始化它?
2条答案
按热度按时间wswtfjt71#
Typescript不擅长输入传统的
prototype
模式。也就是说,还有一些变通办法。
有没有一种TypeScript方法可以声明字段存在,而不必在示例中初始化它?
是的,使用
declare
。其编译为:
并按照您的期望:
declare
是一个仅限类型的构造,并告诉Typescript假装它存在。因此,您
declare
canFly
属性,现在不必向编译器证明该属性存在。见Playground
declare
不是类型安全的,因为它只是在使用时假装一个值存在。如果误用,这可能会导致严重的类型安全问题。在生产代码中几乎不要使用它。nue99wik2#
Alex Wayne
在这方面客观上是正确的,我只想强调他回答的一部分。declare
是一个非常有用但非常危险的关键字。它可以让你的东西编译得很好,但实际上可能会在运行时破坏东西。我个人只建议当你试图在TS代码中采用一个旧的、经过测试的JS库时使用它。declare
就像在说:“假设这是真的。即使不是,也要假设它是真的。”使用时要非常谨慎;因为几乎总是有更好的解决办法。