在普通JavaScript中,很容易设置类的原型字段:
class Bird {
static {
this.prototype.canFly = true;
}
}
new Bird().canFly // true
然而,在TypeScript中,编译器会抱怨该属性不存在。我们可以用@ts-ignore
标记有错误的行,它会工作,但这样我们就失去了对该字段的智能感知和类型检查。
同样,我们不能显式声明类字段,因为这样我们就需要初始化该字段,这就违背了建立原型的目的。
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方法可以声明字段存在而不必在实例中初始化它?
Typescript不擅长输入传统的prototype
模式。
话虽如此,还是有办法的。
是否有一种TypeScript方法可以声明该字段存在而不必在实例中初始化它?
有declare
。
class Bird {
declare canFly: boolean
clipWings() {
this.canFly = false
}
}
Bird.prototype.canFly = true
编译为:
class Bird {
clipWings() {
this.canFly = false;
}
}
Bird.prototype.canFly = true;
做你想做的事:
const wildBird = new Bird()
console.log(wildBird.canFly) // true
const cagedBird = new Bird()
cagedBird.clipWings()
console.log(cagedBird.canFly) // false
// only the instance got clipped
console.log(wildBird.canFly) // true
declare
是一个仅类型的构造,它告诉Typescript假装它存在。
所以你declare
canFly
属性,现在不需要向编译器证明该属性存在。
看到操场
重要提示:declare
不是类型安全的,因为它只是在使用时假装存在一个值。如果使用不当,可能会导致严重的类型安全问题。除非绝对必要,否则避免在产品代码中使用。