簡體   English   中英

在 typescript class 上定義屬性而不定義類型的方法

[英]Way to define properties on typescript class without defining type

我在Time下面有一個 class 。 我很好奇是否有一種方法可以定義語法上不同的 3 個屬性,最好以一種我不必定義上述屬性的方式。

export class Time {
  parsed: ParsedTime
  string: string
  minutes: number
  constructor (public time: TimeConstructable) {
    this.parsed = parseResolve(this.time); 
    this.string = toString(this.parsed)
    this.minutes = inMinutes(this.parsed);
  }
}

我已經嘗試過了,但它不起作用,因為它們在初始化之前運行並且無權訪問this.time

export class Time {
  constructor (public time: TimeConstructable) {}

  parsed = parseResolve(this.time); 
  string = toString(this.parsed)
  minutes = inMinutes(this.parsed);
}

Getter 很好,語法簡潔,但每次檢索屬性時都會計算值,而不是像第一個示例中那樣緩存:

export class Time {
  constructor (public time: TimeConstructable) {}

  get parsed () {
    return parseResolve(this.time); 
  }
  
  get string () {
    return toString(this.parsed)
  }

  get minutes () {
    return inMinutes(this.parsed);
  }
}

這有點不正統,但它是一種有趣的語法,缺點是它允許復雜且無意的構造函數類型。

export class Time {
  constructor (
    public time: TimeConstructable,
    public parsed = parseResolve(time),
    public string = toString(parsed),
    public minutes = inMinutes(parsed)
  ) {}
}

還有其他人嗎?

class 在這里沒有為您做任何有用的事情,因為它沒有任何方法。 類很好地將實例數據對該數據進行操作的方法聯系在一起——但如果其中一個缺失,則使用普通的 function 或普通的 object 更有意義。

這可能不適合您的實際用例,但鑒於問題中的代碼,您可能會使用以下內容:

export const makeTime = (time: TimeConstructable) => ({
  parsed: parseResolve(time),
  string: toString(parsed),
  minutes: inMinutes(parsed),
});

然后根本不需要類型注釋。

(就個人而言,我更喜歡避免使用類的原因之一是因為函數更易於鍵入 - TypeScript 的自動推理可以為您完成幾乎所有的類型工作,讓您只專注於程序的邏輯)

不幸的是,class 語法需要明確的成員聲明。

話雖這么說,正如您所知道的,有一個方便的 TypeScript 簡寫,可讓您直接將它們聲明為構造函數 arguments,因為以這種方式分配它們很常見。 使用這種方法,我們只能編寫一次。

但該速記僅適用於直接分配。 如果您嘗試將其與轉換結合使用,則需要不常見的邏輯,這會導致您指出的漏洞。

常見的解決方案確實是像在第一個示例中那樣編寫它:顯式成員聲明、轉換方法以及在構造函數主體中分配轉換后的值。 這使您至少可以編寫兩次成員名稱,或者如果您有單獨的轉換方法(如果您稍后需要更新值很有用),甚至更多。

另一個解決方案確實利用了吸氣劑。

每次檢索屬性時都會計算 Getters [...] 值,而不是像第一個示例中那樣緩存

一個經典的解決方法是結合私有緩存實現惰性計算(正如您所做的那樣)。 例如:

class Time {
  private _parsed: ParsedTime;

  get parsed() {
    // if not cached yet, lazy evaluate
    // (I assume null and undefined are not expected results)
    this._parsed ??= parseResolve(this.time);
    return this._parsed;
  }
}

IIRC,應該有一些庫為這個用例提供裝飾器,因為它也很常見。 但是自己寫也不是很復雜。 使用這樣的裝飾器,您可能需要更少的寫作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM