簡體   English   中英

打字稿用函數創建自己的類型

[英]Typescript creating own types with functions

我正在嘗試創建我自己的類型,我可以使用dot syntax在其上調用函數。

例如:

let myOwnType: myByteType = 123211345;
myOwnType.toHumanReadable(2);

我想存檔相同的行為,如數字、數組等。我不想使用調用簽名或構造函數簽名創建我的類型

因此,在查看打字稿庫后,我看到了這個數字界面:

interface Number {
    /**
     * Returns a string representation of an object.
     * @param radix Specifies a radix for converting numeric values to strings. This value is only used for numbers.
     */
    toString(radix?: number): string;

    /**
     * Returns a string representing a number in fixed-point notation.
     * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.
     */
    toFixed(fractionDigits?: number): string;

    /**
     * Returns a string containing a number represented in exponential notation.
     * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.
     */
    toExponential(fractionDigits?: number): string;

    /**
     * Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits.
     * @param precision Number of significant digits. Must be in the range 1 - 21, inclusive.
     */
    toPrecision(precision?: number): string;

    /** Returns the primitive value of the specified object. */
    valueOf(): number;
}

問題是我找不到函數體的定義位置和方式。 我在想必須有一個類實現接口或類似的東西。

我想出來嘗試這樣的事情:

interface Bytes {
  toHumanReadable(decimals: number): bytesToHumanReadable;
  bytesAs(unit: string): string;
}


function bytesToHumanReadable (decimals: number) {
  // convert bytes to GB, TB etc..
}

我如何創建自己的類型並像普通類型一樣使用它們? 我知道接口也不起作用,但這是我的第一個猜測。

問題是我找不到函數體的定義位置和方式。

它們由 JavaScript 引擎定義,作為標准庫的一部分。 你會在Number.prototype上找到它們。 它的工作原理如下:當您嘗試訪問基元(例如someNumber.toString() )上的屬性時,JavaScript 引擎會在該基元的對象類型(number => Number , string => String等)。 如果您進行調用,它會調用該方法,傳入原語(在嚴格模式下)或原語的對象包裝器(在松散模式下)。

您無法定義自己的原始類型,只能在 JavaScript 規范級別完成。

您可以創建一個Byte類並擁有它的實例,但它們是對象,而不是基元。

class Byte {
    constructor(public value: number) {
    }
    yourMethodHere() {
        // ...
    }
}

您還可以向Number.prototype添加方法,但最好不要在您可能與他人共享的任何庫代碼中這樣做。 (在您自己的應用程序或頁面中,大多數情況下都可以,只需確保使用標准庫未來功能不太可能使用的名稱即可。)

例如,這向數字添加了一個toHex方法:

// Adding it to the type
interface Number {
    toHex(): string;
}
// Adding the implementation
Object.defineProperty(Number.prototype, "toHex", {
    value() {
        return this.toString(16);
    },
    enumerable: false, // This is the default, but just for emphasis...
    writable: true,
    configurable: true
});

操場上的活生生的例子

TJ Crowder 很好的答案,我對此進行了擴展

 interface myByteType extends Number {
      toHumanReadable?(): string;
     }

    // Adding the implementation
    Object.defineProperty(Number.prototype, "toHumanReadable", {
      value() {
          return this.toString(16);
      },
      enumerable: false, // This is the default, but just for emphasis...
      writable: true,
      configurable: true
    });

    let a: myByteType = 2124;
    a.toHumanReadable();

使用問號語法,您有一種解決方法可以將您自己的類型與您定義的函數一起使用!

您已經完成了bytesToHumanReadable函數的一半,但您錯過了一件關鍵的事情。

由於您想為數字添加新功能,您必須擴展基本NumberConstructor接口並自己實現該功能。 讓我們在實踐中看看這個。

interface myByteType extends NumberConstructor = {
 toHumanReadable: (decimals: number): string
}

這只是為了滿足 TypeScript 編譯器。 您仍然需要通過擴展Number原型來自己實現功能,如下所示:

Number.prototype.toHumanReadable = function(decimals: number) {
 // convert bytes to GB, TB etc.. 
}

然后,您可以對任何擴展myByteType接口的變量使用toHumanReadable函數,如下所示:

const secondsSinceOpened: myOwnType = 1334244200

secondsSinceOpened.toHumanReadable(2)

這個問題是非常相似, 這一個,所以你可以檢查它進一步閱讀。

暫無
暫無

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

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