简体   繁体   English

Typescript:缩短简单 Class 声明

[英]Typescript: Shortening Simple Class Declaration

I have a TS code pattern that I find very useful but it is extremely not DRY .我有一个 TS 代码模式,我觉得它非常有用,但它非常不DRY Any ideas how to fix it?任何想法如何解决它?

I like to "link" together a TS interface with a class declaration.我喜欢将 TS interfaceclass声明“链接”在一起。 In this way I have the advantage of some simple typed data-structure with inheritance, AND I can easily do type checks at runtime with a instanceof operator (that allows me to avoid type predicates , which I find unsafe).通过这种方式,我具有 inheritance 的一些简单类型数据结构的优势,并且我可以在运行时使用instanceof运算符轻松进行类型检查(这使我可以避免类型谓词,我认为这是不安全的)。

For an example see the code below, where I have a class Doctor which extends a base class Person例如,请参见下面的代码,其中我有一个 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

Everything works, the type check is easy and my IntelliSense is happy.一切正常,类型检查很容易,我的 IntelliSense 很高兴。 All great.都很棒。 But as you can see I am repeating myself 3 times for each class.但正如你所看到的,我对每个 class 重复了 3 次。 One time to declare the interface , another to implement it in the class and a final one to apply the constructor .一次声明interface ,另一次在class中实现它,最后一次应用constructor

Isn't there a more coincise way?没有更简洁的方法吗? In a big project this becomes horrible to look at.在一个大项目中,这看起来很可怕。

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)它们仅用于呈现数据,而不是行为(实际上我正在使用它们来填充vuex存储)

First of all, there is no magic syntax to make this nicer.首先,没有神奇的语法可以让它变得更好。

But it is worth noting that a class can be used as an interface:但值得注意的是,可以使用一个 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)

You may think that is a bit odd, but the plain object and the instance of Person both have the exact same public interface, so they are considered compatible.您可能认为这有点奇怪,但普通的 object 和Person的实例都具有完全相同的公共接口,因此它们被认为是兼容的。


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)它们仅用于呈现数据,而不是行为(实际上我正在使用它们来填充 vuex 存储)

So why are you using classes at all?那么你为什么要使用类呢? Then there's no need.那么就没有必要了。 A plain object that conforms to that interface is more or less indistinguishable from the instance of a class that implements that interface, so you can save a lot of boilerplate with just:符合该接口的普通 object 与实现该接口的 class 实例或多或少无法区分,因此您可以节省大量样板文件:

interface Person {
  id: number
  name: string
  surname: string
}

const person: Person = { id: 123, name: 'Al', surname: 'Bundy' }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM