簡體   English   中英

TypeScript接口簽名“():字符串”

[英]TypeScript interface signature “(): string”

在標准Node.js庫的類型定義中,我找到了接口DateConstructor的定義。

interface DateConstructor {
    new(): Date;
    new(value: number): Date;
    new(value: string): Date;
    new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
    (): string;
    readonly prototype: Date;
    /**
      * Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970.
      * @param s A date string
      */
    parse(s: string): number;
    /**
      * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date.
      * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.
      * @param month The month as an number between 0 and 11 (January to December).
      * @param date The date as an number between 1 and 31.
      * @param hours Must be supplied if minutes is supplied. An number from 0 to 23 (midnight to 11pm) that specifies the hour.
      * @param minutes Must be supplied if seconds is supplied. An number from 0 to 59 that specifies the minutes.
      * @param seconds Must be supplied if milliseconds is supplied. An number from 0 to 59 that specifies the seconds.
      * @param ms An number from 0 to 999 that specifies the milliseconds.
      */
    UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;
    now(): number;
}

declare const Date: DateConstructor;

它包含奇怪的定義(): string 如何在要實現此接口的類中定義它?

如果您認為此問題與我鏈接的另一個問題足夠不同:

這個定義意味着類構造函數也是一個沒有參數的可調用函數,當不使用new調用時,該函數將返回字符串。 您不能使用ES2015或 更高版本的 class並遵守規范,因為在沒有new情況下調用它時需要引發TypeError 相反,您可以返回一個檢測到new調用的函數,並添加了額外的屬性以實現靜態方法。

我將為您提供一個示例,其中為內置的Date構造函數對象提供包裝。 首先,讓我們描述一下界面功能類似於或不帶有new關鍵字的部分:

interface FunctionalPartOfDateConstructor {
  new(): Date;
  new(value: number): Date;
  new(value: string): Date;
  new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
  (): string;
}

現在讓我們嘗試實現這一部分:

const funcPart = function(valueOrYear?: number | string, month?: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date | string {
  if (typeof new.target === 'undefined') {
    // called as function
    return Date();
  }
  if (typeof valueOrYear === 'undefined') {
    // called as constructor with no arguments
    return new Date();
  }
  if (typeof valueOrYear === 'string') {
    // called as constructor with string value argument
    return new Date(valueOrYear);
  }
  if (typeof month === 'undefined') {
    // called as constructor with number value argument
    return new Date(valueOrYear);
  }
  // called as constructor with year, month, date, etc arguments:
  return new Date(valueOrYear, month, date, hours, minutes, seconds, ms);
} as FunctionalPartOfDateConstructor;

請注意,我使用new.target來檢測是否使用new調用了該函數。 我認為,在針對ES5時,這可以編譯為合理的內容。 並請注意,它必須弄清楚所有不同的過載簽名之間的區別。

現在,我們可以通過將功能部分與實現靜態方法的東西合並來制作完整的DateConstructor實例:

const myDateConstructor: DateConstructor = Object.assign(funcPart, {
  prototype: Date.prototype,
  parse(s: string) {
    return Date.parse(s);
  },
  UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number) {
    return Date.UTC(year, month, date, hours, minutes, seconds, ms);
  },
  now() {
    return Date.now();
  }
})

如果需要,可以在TypeScript游樂場上嘗試一下 希望能有所幫助; 祝好運!

暫無
暫無

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

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