2017-05-26 68 views
1

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

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 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 

然而,我的解决方案未能在以下几点:

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

我该如何绕过这些问题?有没有更好的设计模式,我在这里失踪?

回答

0

既然我不能定义一个静态的抽象功能,这里是我使出了实施:

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))) } 
} 

底线:我必须定义在我的所有对象,并列出静态fromJSON()方法类。这些方法不是那么复杂,所以这是一个舒适的双赢。 =)