網站搜尋

Typescript 介面屬性作為類型化函數參數未被強制執行


我有這個介面:

interface Field {
  type: string;
  value: (argument1: string, argument2: string) => string;
}

const field: Field = {
  type: 'text',
  value: () => 'Hello'
};

為什麼 TypeScript 沒有強制執行 argument1 和 argument2?這段代碼可以順利編譯,我希望 TypeScript 確保這個函數完全按照我在介面定義中所輸入的方式。

答案#1

為什麼 TypeScript 沒有強制要求 argument1 和 argument2?

該類型的目的是強制在調用函數時必須傳遞那些參數。然而,該類型並不意味著函數必須對那些參數執行任何操作。像下面這樣編寫函數是合法的,它列出參數但對其不做任何操作:

value: (argument1: string, argument2: string) => 'Hello'

不過那只是額外的打字,沒有任何好處,因為 JavaScript 函數可以接受任何數量的參數,不管列出了哪些。因此 TypeScript 也允許你不去列出它們,同時仍然與類型兼容。如果你列出了一個類型不匹配的參數,它會告訴你,但省略掉則不成問題。

TypeScript 是刻意這樣設計的。請參閱文件的這一部分:https://www.typescriptlang.org/docs/handbook/type-compatibility.html#comparing-two-functions

你可能會想知道為什麼我們允許像範例 y=x 這樣的「丟棄」參數。允許這種賦值的原因是,忽略多餘的函式參數在 JavaScript 中其實相當常見。例如,Array#forEach 為回呼函式提供三個參數:陣列元素、其索引以及包含它的陣列。儘管如此,提供一個只使用第一個參數的回呼函式仍然非常有用:

let items = [1, 2, 3];

// Don't force these extra parameters
items.forEach((item, index, array) => console.log(item));

// Should be OK!
items.forEach(item => console.log(item));