2017-06-01 52 views
1

我有下面的類結構...JSON.stringify序列只有打字稿干將

export abstract class PersonBase { 
    public toJSON(): string { 
     let obj = Object.assign(this); 
     let keys = Object.keys(this.constructor.prototype); 
     obj.toJSON = undefined; 
     return JSON.stringify(obj, keys); 
    } 
} 

export class Person extends PersonBase { 

    private readonly _firstName: string; 
    private readonly _lastName: string; 

    public constructor(firstName: string, lastName: string) { 
     this._firstName = firstName; 
     this._lastName = lastName; 
    } 

    public get first_name(): string { 
     return this._firstName; 
    } 

    public get last_name(): string { 
     return this._lastName; 
    } 
} 

export class DetailPerson extends Person { 

    private _address: string; 

    public constructor(firstName: string, lastName: string) { 
     super(firstName, lastName); 
    } 

    public get address(): string { 
     return this._address; 
    } 

    public set address(addy: string) { 
     this._address = addy; 
    } 
} 

我想獲得的toJSON()輸出所有從完整對象層次的吸氣劑(不包括私人性質) ...

所以,如果我有一個DetailPerson實例,我叫.toJSON()我想看到下面的輸出...

{ 「地址」: 「有些地址」, 「FIRST_NAME」 :「我的名字」, 「last_name」:「我的姓氏」 }

我使用了本文中的解決方案之一,但它並未解決我的特殊使用案例...我沒有在輸出中獲取所有獲取者。

Using JSON.stringify in conjunction with TypeScript getter/setter

我需要什麼改變這裏得到的結果我找的?

+0

有你定義的方法'toJsonString'雙方的'Person'和'DetailPerson'類,如你所鏈接的帖子所示?我沒有看到他們在您發佈的代碼中定義。 – gforce301

+0

請提供[mcve],顯示您正在嘗試解決的確切問題。 –

+0

修改。 – Daz

回答

1

您提供的鏈接使用Object.keys,它遺留了原型上的屬性。

你可以使用for...in代替Object.keys

public toJSON(): string { 
    let obj: any = {}; 

    for (let key in this) { 
     if (key[0] !== '_') { 
      obj[key] = this[key]; 
     } 
    } 

    return JSON.stringify(obj); 
} 

編輯:這是我試圖返回只干將,遞歸,沒有假設非干將開始用下劃線。我敢肯定有陷阱,我錯過(循環引用,與特定類型的問題),但它是一個良好的開端:

abstract class PersonBase { 
    public toJSON(): string { 
    return JSON.stringify(this._onlyGetters(this)); 
    } 

    private _onlyGetters(obj: any): any { 
    // Gotchas: types for which typeof returns "object" 
    if (obj === null || obj instanceof Array || obj instanceof Date) { 
     return obj; 
    } 

    let onlyGetters: any = {}; 

    // Iterate over each property for this object and its prototypes. We'll get each 
    // property only once regardless of how many times it exists on parent prototypes. 
    for (let key in obj) { 
     let proto = obj; 

     // Check getOwnPropertyDescriptor to see if the property is a getter. It will only 
     // return the descriptor for properties on this object (not prototypes), so we have 
     // to walk the prototype chain. 
     while (proto) { 
     let descriptor = Object.getOwnPropertyDescriptor(proto, key); 

     if (descriptor && descriptor.get) { 
      // Access the getter on the original object (not proto), because while the getter 
      // may be defined on proto, we want the property it gets to be the one from the 
      // lowest level 
      let val = obj[key]; 

      if (typeof val === 'object') { 
      onlyGetters[key] = this._onlyGetters(val); 
      } else { 
      onlyGetters[key] = val; 
      } 

      proto = null; 
     } else { 
      proto = Object.getPrototypeOf(proto); 
     } 
     } 
    } 

    return onlyGetters; 
    } 
} 
+0

謝謝......理想情況下,我希望有一種更通用的解決方案,這種解決方案並沒有對我如何命名私有財產與getters \ setter進行假設。在這種情況下,我的私人財產被命名爲firstName和getter \ setter是First_Name或任何其他變體,這將無法正常工作。我應該更清楚地表達我的問題,道歉。 – Daz

+0

我編輯了我的回覆。讓我知道這是否適合你。 –

+0

這樣做,謝謝先生! – Daz