【问题标题】:How to ensure that an extending class must set property values in TypeScript?如何确保扩展类必须在 TypeScript 中设置属性值?
【发布时间】:2017-09-08 15:59:23
【问题描述】:
如果我有课foo:
class Foo {
id: number
name: string
sayHi() {
console.log('hi')
}
}
如何确保从 foo 扩展的任何类都必须为 id 和 name 设置值?
class Bar extends Foo {
// must set these values
id = 1
name = 'bar'
}
这个概念或模式有名称吗?我不能将Foo 作为接口,因为它必须有方法,继承的类可以使用。
【问题讨论】:
标签:
javascript
oop
inheritance
typescript
【解决方案1】:
给Foo一个需要它们作为参数的构造函数:
class Foo {
constructor(public id: number, public name: string) {
// Validate them here if desired
}
sayHi() {
console.log('hi');
}
}
由于子类必须调用其超类构造函数(隐式或显式),因此在不传递必要参数的情况下尝试这样做会被 TypeScript 编译器标记:Supplied parameters do not match any signature of call target. 例如,这两种方法都会失败:
class Bar extends Foo {
}
const b = new Bar(); // Supplied parameters do not match any signature of call target.
和
class Bar extends Foo {
constructor() {
super(); // Supplied parameters do not match any signature of call target.
}
}
注意这里使用的有趣的 TypeScript 特性:因为我们在构造函数参数上提供了访问修饰符,所以实例属性会在构造函数被调用时自动创建并设置为这些值。相当于:
class Foo {
id: number;
name: string;
constructor(id: number, name: string) {
this.id = id;
this.name = name;
// Validate them here if desired
}
sayHi() {
console.log('hi');
}
}
(因为默认修饰符是public。)