我需要一些有关打字稿中抽象的帮助。
我想限制成员只接受类型作为值,但是这些类型需要实现或扩展其他类型或接口。
例如。
以下示例不代表真实数据模型或与之相关,而是说明目标的示例。
interface Profession {
work()
}
class Engineer implements Profession {
work() {...}
}
class Doctor {
work() {...}
}
interface ProfessionRankingMap {
top1ProfessionType: // Here is where I don't know how to constraint
top2ProfessionType: // Here is where I don't know how to constraint
}
const classAProfessionRankingMap: ProfessionRankingMap {
// This is okay, Type Engineer implements Profession interface
top1ProfessionType: Engineer
// This is bad, Type Doctor doesn't implement Profession interface
top2ProfessionType: Doctor
}
const classBProfessionRankingMap: ProfessionRankingMap {
// This is bad, [new Engineer()] returns an instance not a type
top1ProfessionType: new Engineer()
// This is bad, [new Doctor()] returns an instance not a type
top2ProfessionType: new Doctor()
}
答案 0 :(得分:1)
要以类型表示类,您需要构造函数签名:
interface ProfessionRankingMap {
// The implementer must have a constructor with no args that returns Profession
top1ProfessionType: new () => Profession
top2ProfessionType: new () => Profession
}
const classAProfessionRankingMap: ProfessionRankingMap = {
top1ProfessionType: Engineer,
top2ProfessionType: Doctor
}
如果我们想接受具有任意数量参数的构造函数的类,则可以使用new (... args:any[]) => Profession
。
问题的第二部分要复杂一些。 Typescript使用结构化类型确定类型兼容性。因此,类的结构与implements
子句无关。 implements
子句只会在声明类时为您提供错误,并确保它具有所有必需的成员,因此您尽早获得错误,而不是在尝试使用需要接口的类时提早得到错误。
这意味着,只要Doctor
拥有Profession
的所有成员,就无法阻止它在期望的Profession
处传递。
唯一的解决方案是对私有成员使用抽象类。私有成员将确保除扩展抽象类的类之外的其他任何类均不与抽象类类型兼容:
abstract class Profession {
private _notStructural: undefined;
abstract work(): void
}
class Engineer extends Profession {
work() { }
}
class Doctor {
work() { }
}
interface ProfessionRankingMap {
top1ProfessionType: new () => Profession
top2ProfessionType: new () => Profession
}
const classAProfessionRankingMap: ProfessionRankingMap = {
top1ProfessionType: Engineer,
top2ProfessionType: Doctor // error
}