博客 / 詳情

返回

TypeScript 定義函數的幾種寫法

  • 參考鏈接1
  • 參考鏈接2

寫法1 - 使用 function 關鍵字

function greeter(fn: (a: string) => void) {
  fn("Hello, World");
}

function printToConsole(s: string) {
  console.log(s);
}

greeter(printToConsole);
(a: string) => void

上述語法的含義:表示一個函數,接收一個字符串作為輸入參數,沒有返回參數。

可以使用 type 關鍵字定義一個別名:

type GreetFunction = (a: string) => void;

Call signatures

使用 call signatures 給函數增加額外的屬性。TypeScript 的 function 也是 value,和其他 value 一樣。

注意:一定有 type 關鍵字。

源代碼:

type DescribableFunction = {
    description: string;
    (someArg: number): boolean;
  };
  
function doSomething(fn: DescribableFunction) {
    console.log(fn.description + " returned " + fn(6));
}

const fn = (a: number) => a > 10;

fn.description = 'Jerry';

另一種定義方式:

type DescribableFunction = {
    description: string;
    (someArg: number): boolean;
  };
const fn = <DescribableFunction>({
   description: 'Jerry'
});

const fn23 = Object.assign(
  function (number:number) { return number > 1 },
  fn
);
function doSomething(fn: DescribableFunction) {
    console.log(fn.description + " returned " + fn(6));
}

Construct signatures

type SomeConstructor = {
  new (s: string): SomeObject;
};
function fn(ctor: SomeConstructor) {
  return new ctor("hello");
}

Method Signatures

方法簽名語法可能是最容易使用的。 在定義對象類型時,可以通過提供如下簽名來輕鬆描述其方法:

interface Date {
  toString(): string;
  setTime(time: number): number;
  // ...
}

看個例子:

通過這種方式定義出來的函數,實際是一個 object:

如何實例化這種類型的 object?

const myDate = <MyDate>({
  toString: () => 'Jerry',
  setTime: (number) => number + 1
});

Function Type Literals

Function Type Literals 是另一種聲明函數類型的方法。 它們通常用於高階函數的簽名,即接受函數作為參數或返回函數的函數:

interface Array<T> {
  sort(compareFn?: (a: T, b: T) => number): this;
  // ...
}

也許令人驚訝的是,在函數類型文字中總是需要參數名稱。 您不能省略參數名稱而只指定類型。

如果忘記指定形參名稱,我們將無法得到期望的類型定義。下面的代碼是一個例子:

我們本意想定義一個擁有兩個輸入參數,一個返回參數的函數類型,輸入參數類型分別為 string 和 number.

type FunctionType2 = (string, number) => number;
// (string: any, number: any) => number

實際上,TypeScript 編譯器將 string 和 number 理解成了形式參數名,且類型為 any. 這就和我們的期望不一致了。

總結一下:

Object Type Literals with Call or Construct Signatures

在 JavaScript 中,函數只不過是可以調用的特殊對象。 這個事實反映在對象類型文字的語法中:它們描述了對象的形狀,它也恰好有一個調用簽名:

interface RegExpConstructor {
  // Call signatures
  (pattern: RegExp): RegExp;
  (pattern: string, flags?: string): RegExp;

  // ...
}

與調用簽名類似,對象類型文字也可以包含構造簽名,在這種情況下,它被稱為構造函數類型。 當使用 new 運算符調用函數時,函數的構造簽名定義了它的參數列表和返回類型。 構造簽名看起來與調用簽名幾乎相同,除了它們額外帶有 new 關鍵字前綴:

interface RegExpConstructor {
  // Call signatures
  (pattern: RegExp): RegExp;
  (pattern: string, flags?: string): RegExp;

  // Construct signatures
  new (pattern: RegExp): RegExp;
  new (pattern: string, flags?: string): RegExp;

  // ...
}
// Using the call signature
const digitsPattern1 = RegExp("^\\d+$");

// Using the construct signature
const digitsPattern2 = new RegExp("^\\d+$");

更多Jerry的原創文章,盡在:"汪子熙":

user avatar jiaozheng 頭像
1 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.