打字稿:缩短简单 Class 声明
Typescript: Shortening Simple Class Declaration
我有一个 TS 代码模式,我觉得它非常有用,但它非常不 DRY。有什么解决办法吗?
我喜欢将 TS interface
与 class
声明一起“link”。通过这种方式,我拥有一些具有继承性的简单类型数据结构的优势,并且我可以在运行时使用 instanceof
运算符轻松地进行类型检查(这让我可以避免 type predicates,我发现它不安全).
例如,请参见下面的代码,其中我有一个 class Doctor
扩展了一个基础 class Person
interface PersonInterface {
id: number
name: string
surname: string
}
class Person implements PersonInterface {
id: number
name: string
surname: string
constructor(arg: PersonInterface) {
this.id = arg.id
this.name = arg.name
this.surname = arg.surname
}
}
interface DoctorInterface extends PersonInterface {
degree: string
salary: number
}
class Doctor extends Person implements DoctorInterface {
degree: string
salary: number
constructor(arg: DoctorInterface) {
super(arg)
this.degree = arg.degree
this.salary = arg.salary
}
}
const doc = new Doctor({
id: 111,
name: 'John',
surname: 'Johnson',
degree: 'PHD',
salary: 100000,
})
console.log(doc instanceof Person) // true
console.log(doc instanceof Doctor) // true
一切正常,类型检查很简单,我的 IntelliSense 很满意。一切都很棒。但是正如您所看到的,我为每个 class 重复了 3 次。一次声明 interface
,另一次在 class
中实现它,最后一次应用 constructor
.
有没有更简洁的方法?在一个大项目中,这变得很难看。
重要
我的 classes 中不需要方法。它们仅用于呈现数据,而不是行为(事实上我正在使用它们来填充 vuex 存储)
首先,没有神奇的语法可以让它变得更好。
但是值得注意的是,一个class可以作为一个接口:
class Person {
id: number
name: string
surname: string
constructor(arg: Person) {
this.id = arg.id
this.name = arg.name
this.surname = arg.surname
}
}
// works
const personData: Person = { id: 123, name: 'Al', surname: 'Bundy' }
const person: Person = new Person(personData)
您可能认为这有点奇怪,但是普通对象和 Person
的实例都具有完全相同的 public 接口,因此它们被认为是兼容的。
IMPORTANT I do not need to have methods in my classes. They are used only to rapresent data, not behaviour (in fact I am using them to populate a vuex store)
那你为什么要使用 classes?那就没必要了。符合该接口的普通对象与实现该接口的 class 的实例或多或少没有区别,因此您只需使用以下代码即可节省大量样板文件:
interface Person {
id: number
name: string
surname: string
}
const person: Person = { id: 123, name: 'Al', surname: 'Bundy' }
我有一个 TS 代码模式,我觉得它非常有用,但它非常不 DRY。有什么解决办法吗?
我喜欢将 TS interface
与 class
声明一起“link”。通过这种方式,我拥有一些具有继承性的简单类型数据结构的优势,并且我可以在运行时使用 instanceof
运算符轻松地进行类型检查(这让我可以避免 type predicates,我发现它不安全).
例如,请参见下面的代码,其中我有一个 class Doctor
扩展了一个基础 class Person
interface PersonInterface {
id: number
name: string
surname: string
}
class Person implements PersonInterface {
id: number
name: string
surname: string
constructor(arg: PersonInterface) {
this.id = arg.id
this.name = arg.name
this.surname = arg.surname
}
}
interface DoctorInterface extends PersonInterface {
degree: string
salary: number
}
class Doctor extends Person implements DoctorInterface {
degree: string
salary: number
constructor(arg: DoctorInterface) {
super(arg)
this.degree = arg.degree
this.salary = arg.salary
}
}
const doc = new Doctor({
id: 111,
name: 'John',
surname: 'Johnson',
degree: 'PHD',
salary: 100000,
})
console.log(doc instanceof Person) // true
console.log(doc instanceof Doctor) // true
一切正常,类型检查很简单,我的 IntelliSense 很满意。一切都很棒。但是正如您所看到的,我为每个 class 重复了 3 次。一次声明 interface
,另一次在 class
中实现它,最后一次应用 constructor
.
有没有更简洁的方法?在一个大项目中,这变得很难看。
重要 我的 classes 中不需要方法。它们仅用于呈现数据,而不是行为(事实上我正在使用它们来填充 vuex 存储)
首先,没有神奇的语法可以让它变得更好。
但是值得注意的是,一个class可以作为一个接口:
class Person {
id: number
name: string
surname: string
constructor(arg: Person) {
this.id = arg.id
this.name = arg.name
this.surname = arg.surname
}
}
// works
const personData: Person = { id: 123, name: 'Al', surname: 'Bundy' }
const person: Person = new Person(personData)
您可能认为这有点奇怪,但是普通对象和 Person
的实例都具有完全相同的 public 接口,因此它们被认为是兼容的。
IMPORTANT I do not need to have methods in my classes. They are used only to rapresent data, not behaviour (in fact I am using them to populate a vuex store)
那你为什么要使用 classes?那就没必要了。符合该接口的普通对象与实现该接口的 class 的实例或多或少没有区别,因此您只需使用以下代码即可节省大量样板文件:
interface Person {
id: number
name: string
surname: string
}
const person: Person = { id: 123, name: 'Al', surname: 'Bundy' }