TypeScript全解:深入對象與函數(shù)(下)

函數(shù)重載(overload)

什么是函數(shù)重載?簡單來說就是同名的函數(shù),這個概念是從 java 來的

我們來看這個需求,一個方法接受的參數(shù)有兩種情況,可能是 number,可能是 string

如果用 TS 來實現(xiàn),非常簡單

class X {
  method(n: number | string) {
    /* ... */
  }
}

但是 java 不支持這種情況的聯(lián)合類型,但是遇到這種需求該怎么辦呢?java 的設計者當時又不想直接弄出這么個聯(lián)合類型,那干脆讓一個方法寫兩遍好了

class X {
  method(n: number) {
    /* ... */
  }
  method(n: string) {
    /* ... */
  }
}

于是 java 就誕生了一個新語法,一個類的方法是可以同名的,用你的參數(shù)類型和個數(shù)來判斷會具體執(zhí)行那個函數(shù)(很奇怪的語法吧~)

所以重載是為了解決 java 的一個問題

其實在很久之前大家都應該接觸過函數(shù)重載,在 JQuery 時代的 Selector 一樣

$('#div')
$(window)
$...

也許內(nèi)部使用了大量的 if else,所以說 js 不需要重載這個特性,也能做出一樣的效果

但是說回 TS,我認為只有這些情況可能需要用重載

一個創(chuàng)建日期的函數(shù),可以接受一個數(shù)量 number,也能接受具體的日期

function createData(n: number): Date
function createData(year: number, month: number, date: number): Date
 // TODO: 注意:下面這里會和 java 稍微不同一點
function createData(a: number, b?: number, c?: number): Date { // TODO: 最后一個實現(xiàn)的簽名需要兼容上面所有的情況
  if (a !== undefined && b !== undefined && c !== undefined) {
    return new Date(a,b,c)
  } else if (a !== undefined && b === undefined && c === undefined) {
    return new Date(a)
  } else {
    throw new Error('只接受一個或三個參數(shù)')
  }
}

也許也能用聯(lián)合類型?if else 實現(xiàn)出來,但是重載會更優(yōu)雅一點

但是我個人依然保持能不用就不用的態(tài)度看待它,就算遇到這種問題,為何非要用一個函數(shù)來解決,用兩個不同名稱的函數(shù)來不香么,createDataByNumber 和 createDataByYMD

其實如果你是一個庫的封裝者,像 JQuery 一樣,把函數(shù)封裝的復雜度留給自己,使用函數(shù)重載能方便使用者
但如果你是想把函數(shù)的使用權交給用戶,就應該多明明幾個函數(shù)提供用戶任意組合使用

this

在 TS 中怎么定義 this 的類型呢?

type Person {
  name: string;
}
function fn(this: Person, word: string) { // TODO: 這個地方好奇 this 為什么會在參數(shù)上的人,請看我的 javascript-this 文章
  console.log(this.name, word)
}

fn('hi') // TODO: 報錯

this 在參數(shù)上了,那么該如何調(diào)用呢?看下面幾種方法:

// 強行拼湊出 person.fn()
const p: Person & { fn: typeof fn } = { name: 'jack', fn }
p.fn('hi')

// fn.call()
fn.call({ name: 'jack' }, 'hi')

// fn.apply()
fn.apply({ name: 'jack' }, ['hi'])

// fn.bind()
fn.bind({ name: 'jack' })('hi')

... 與 參數(shù)

剩余參數(shù)

function sum(...x: number[]) {
  return x.reduce((a,b) => a + b, 0)
}

sum(1)
sum(1,2,3,4,5)
sum(1,2,3,4,5,6,7,8,9)

展開參數(shù)

function sum(name: string, ...rest: number[]) {
  fn(...rest)
  // or
  fn.apply(null, rest)
}

function fn(...x: number[]) {
  console.log(x)
}

as const

我們知道 TS 有自動推導

let a = 'hi'

此時我們很容易看出來 a 的類型是 string
其實這樣可能會有些問題
理論上來說 a 的類型應該可能是 'hi' 或者 string
但是這個 TS 怎么知道我們這個 a 是常量(即類型為 'hi')還是 string 呢?

用 const

let a = 'hi' as const

不對啊,直接用 const 關鍵詞不就好了

const a = 'hi'

其實大多數(shù)的應用場景在對象上,因為 JS 的 const 就是殘廢

const array = [1, 'hi'] as const

參數(shù)對象的析構(gòu)

type Config = {
  url: string;
  method: 'GET' | 'POST' | 'PATCH';
  data?: number;
}

// 使用一
function ajax({ url, method, ...data }: Config) {}

// 使用二
function ajax({ url, method, ...data }: Config = {url: '', method: 'GET'}) {}

// 使用三
function ajax({ url, method, ...data } = {url: '', method: 'GET'} as Config) {}

void

function f1(): void {
  return
}
function f2(): void {
  return undefined
}
function f3(): void {
}
function f4(): void {
  return null // TODO: 報錯
}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容