Generics 类型脚本::抽象静态

Generics 类型脚本::抽象静态,generics,typescript,inheritance,Generics,Typescript,Inheritance,在我的一个个人项目中,我试图设计一些对象和列表类型。对象和列表应该是可序列化的(即有一个toJSON()和fromJSON()方法)。示例对象和列表将具有以下基本代码: type IPerson = { id: number; name: string; // additional properties } class Person { id: number; name: string; // additional properties constructor(id

在我的一个个人项目中,我试图设计一些对象和列表类型。对象和列表应该是可序列化的(即有一个
toJSON()
fromJSON()
方法)。示例对象和列表将具有以下基本代码:

type IPerson = {
  id: number;
  name: string;
  // additional properties
}

class Person {
  id: number;
  name: string;
  // additional properties
  constructor(id: number, name: string, ...) { ... }
  toJSON(): IPerson { return { ... } }
  static fromJSON(json: IPerson): Person { return new Person(...) }
  // additional methods
}

class PersonList {
  list: Person[];
  constructor(list: Person[]) { ... }
  findById(id: number) { return this.list.find(it => it.id === id) }
  findByName(name: string) { return this.list.find(it => it.name === name) }
  add(person: Person) { this.list.push(person) }
  remove(person: Person) { this.list = this.list.filter(it => it !== person) }
  toJSON(): IPerson[] { return this.list.map(it => it.toJSON()) }
  static fromJSON(json: IPerson[]): PersonList { return new PersonList(json.map(it => Person.fromJSON(it))) }
  // additional methods
}
我使用的所有对象和列表至少都有这里列出的方法

现在,我正在尝试将其转换为通用解决方案,以便:

type JSON = {
  id: number;
  name: string;
}

abstract class BaseObject<T extends JSON> {
  abstract get id();
  abstract get name();
  constructor(id: number, name: string) { ... }
  abstract toJSON(): T
  abstract static fromJSON(json: T): BaseObject<T>
}

class BaseList<T, U> {
  list: BaseObject<T>[];
  constructor(list: BaseObject<T>[]) { ... }
  findById(id: number) { return this.list.find(it => it.id === id) }
  findByName(name: string) { return this.list.find(it => it.name === name) }
  add(obj: BaseObject<T>) { this.list.push(obj) }
  remove(obj: BaseObject<T>) { this.list = this.list.filter(it => it !== obj) }
  toJSON(): U[] { return this.list.map(it => it.toJSON()) }
  static fromJSON(json: U[]): BaseList<T, U> { return new BaseList<T, U>(json.map(it => BaseObject<T>.fromJSON(it))) }
}
type JSON={
id:编号;
名称:字符串;
}
抽象类基类对象{
抽象get id();
抽象获取名称();
构造函数(id:number,name:string){…}
抽象toJSON():T
抽象静态fromJSON(json:T):BaseObject
}
类基本列表{
列表:BaseObject[];
构造函数(列表:BaseObject[]){…}
findById(id:number){返回this.list.find(it=>it.id==id)}
findByName(name:string){返回this.list.find(it=>it.name==name)}
添加(obj:BaseObject){this.list.push(obj)}
删除(obj:BaseObject){this.list=this.list.filter(it=>it!==obj)}
toJSON():U[]{返回this.list.map(it=>it.toJSON())}
静态fromJSON(json:U[]):基本列表{返回新的基本列表(json.map(it=>BaseObject.fromJSON(it))}
}
如果这个结构起作用了(它没有),它会让我的生活变得如此简单:

type IPerson = JSON & {
  // additional fields
}

class Person extends BaseObject<IPerson> {
  get id() { ... }
  get name() { ... }
  // additional getters for other fields
  toJSON(): IPerson { return { ... } }
  static fromJSON(json: IPerson): Person { return new Person(...) }
  // additional methods
}

class PersonList extends BaseList<Person, IPerson> {
  // additional methods
}

// other object and list types definitions follow
type IPerson=JSON&{
//其他字段
}
类Person扩展BaseObject{
获取id(){…}
获取名称(){…}
//其他字段的附加getter
toJSON():IPerson{return{…}
静态fromJSON(json:IPerson):Person{returnnewperson(…)}
//附加方法
}
类PersonList扩展了BaseList{
//附加方法
}
//下面是其他对象和列表类型的定义
但是,我的解决方案在以下几点失败:

  • BaseObject
    不能具有抽象静态
    fromJSON()
    方法
  • BaseList
    不能具有抽象静态
    fromJSON()
    方法
  • BaseList.fromJSON()
    无法实例化新列表,也无法调用
    BaseObject.fromJSON()
    来实例化新对象

  • 我如何规避这些问题?有没有更好的设计模式我在这里遗漏了?

    因为我无法定义静态抽象函数,下面是我采用的实现:

    type BaseJson = {
        id: string;
    }
    abstract class BaseObj<U> {
        abstract get id(): string;
        abstract toJSON(): U;
    }
    abstract class BaseList<T extends BaseObj<U>, U> {
        list: BaseObj<U>[] = [];
        add(x: BaseObj<U>) { this.list.push(x) }
        remove(x: BaseObj<U>) { this.list = this.list.filter(it => it !== x) }
        toJSON(): U[] { return this.list.map(it => it.toJSON()) }
    }
    
    type IPerson = BaseJson & {
        name: string;
    }
    class Person extends BaseObj<IPerson> {
        data: IPerson;
        constructor(data: IPerson) { super(); this.data = data }
        get id() { return this.data.id }
        get name() { return this.data.name }
        toJSON(): IPerson { return { id: this.id, name: this.name } }
        static fromJSON(json: IPerson): Person { return new Person(json) }
    }
    class PersonList extends BaseList<Person, IPerson> {
        constructor(list: Person[]) { super(); this.list = list }
        static fromJSON(json: IPerson[]): PersonList { return new PersonList(json.map(it => Person.fromJSON(it))) }
    }
    
    type BaseJson={
    id:字符串;
    }
    抽象类BaseObj{
    抽象get id():字符串;
    抽象toJSON():U;
    }
    抽象类基表{
    列表:BaseObj[]=[];
    添加(x:BaseObj){this.list.push(x)}
    删除(x:BaseObj){this.list=this.list.filter(it=>it!==x)}
    toJSON():U[]{返回this.list.map(it=>it.toJSON())}
    }
    输入IPerson=BaseJson&{
    名称:字符串;
    }
    类Person扩展了BaseObj{
    资料来源:IPerson;
    构造函数(data:IPerson){super();this.data=data}
    get id(){返回this.data.id}
    get name(){返回this.data.name}
    toJSON():IPerson{return{id:this.id,name:this.name}
    静态fromJSON(json:IPerson):Person{returnnewperson(json)}
    }
    类PersonList扩展了BaseList{
    构造函数(list:Person[]){super();this.list=list}
    静态fromJSON(json:IPerson[]):PersonList{返回新的PersonList(json.map(it=>Person.fromJSON(it))}
    }
    
    一句话:我必须在所有对象和列表类中定义静态
    fromJSON()
    方法。这些方法没有那么复杂,因此是一种舒适的双赢