TypeScript 中的命名參數、可選參數、默認參數

對於一些功能比較複雜的函數,須要將不少配置項做爲參數傳入,這時候傳統的位置參數表就不太方便了,由於對於配置項參數,咱們每每會設置默認值,但願使用者無需按順序傳入全部參數,而只要指明哪幾個參數須要特別配置。前端

好比一個簡單的字符串格式化函數,除了必需的傳入值 value 外,有三個配置項:git

  • indent :縮進github

  • caseMode :大小寫面試

  • callback :轉換完成後的回調編程

前端代碼中應該如何定義呢?bash


咱們先看看用 JavaScript 的狀況。編程語言

若是咱們按照最原始的定義方法:函數

function transform(value, indent, caseMode, callback) {
  ...
}
複製代碼

那麼使用者就必須記住全部配置參數的位置,要是隻想設置 caseMode ,須要寫成以下尷尬的形式:spa

transform('someStr', undefined, 'upper')
複製代碼

事實上不少 JavaScript 內置函數就是採用的這種方式,使用者很難記住全部的位置參數,所以[1, 2, 3].map(parseInt) 纔會成爲「經典」面試題。code

不少現代編程語言,好比 Dart 或 Python ,增長了「命名參數」這一特性,解決了參數與參數名對應的問題:

transform('someStr', caseMode: 'upper')
複製代碼

JavaScript 沒有命名參數這一特性,早期實踐中每每經過「配置對象參數「的方式,達到相似的效果:

function transform(value, cfg) {
  ...
  if(cfg.caseMode) ...
}
複製代碼

對象參數的缺點是源碼中 cfg 的配置項不夠直觀,默認值設置比較麻煩,類型檢查約束性不夠。

如今配合上 ES6 的解構賦值和函數默認值,直觀性和默認值能夠解決了:

function transform(value, {
  indent = 2,
  caseMode = 'upper',
  callback,
} = {}) {
  ...
}
複製代碼

不過約束性仍是不夠,不能實現「必選參數」、「可選參數」的功能。


這時候就要 TypeScript 上場了。

除了類型檢查外,TypeScript 能夠對必選參數進行空值檢查,而後再經過?: 手動設置可選參數:

function transform(value: string, {
  indent = 2,
  caseMode = 'upper',
  callback,
}:{
  indent?: number,
  caseMode?: string,
  callback?: (rst: string) => void,
} = {}) {
  ...
}
複製代碼

這就是 TypeScript 中比較完整的一個列子,實現了命名參數、可選參數,參數默認值的功能,使用時:

transform('someStr', { caseMode: 'upper' })
複製代碼

在以上的定義中,「命名參數」用上了 {}: {}={} 的結構進行定義,格式上要分紅兩段,另外因爲本質上是個對象參數,外面仍是不能忘了大括號的,寫法略有些冗長,可是 TypeScript 的團隊 表示 因爲保留位置限制、表達式解析等種種緣由,目前不會加入真正的「命名參數」特性,所以目前只能這樣寫。

相關文章
相關標籤/搜索