TypeScript オーバーロード

オーバーロードされた関数のシグネチャを宣言した後に、実装ではそれらのシグネチャを結合する。

type Reservation = {
    code: string
    dest?: string
}

// Reserve には、出発日、到着日、行先の三つの引数をとるパターンと、出発日、行先の二つの引数をとるパターンがある(日帰り用)
type Reserve = {
    (from: Date, to: Date, destination: string): Reservation
    (from: Date, destination: string): Reservation
}

// 実装では上の二つのシグネチャを合併した型をつける
const reserve: Reserve = (
        from: Date, 
        toOrDestination: Date | string, 
        destination?: string
    ) => {
    if(toOrDestination instanceof Date && destination !== undefined){
        //宿泊処理
        return {
            code: '001',
            dest: destination
        }
    }else if(typeof toOrDestination === 'string'){
        //日帰り処理
        return {
            code: '002',
            dest: destination
        }
    }
    return {
        code: '003'
    }
}

//呼び出すときは、定義したどちらのシグネチャにマッチしていればOK
const reserve1 = reserve(new Date('20210201'), new Date('20210202'), '東京')
const reserve2 = reserve(new Date('20210201'), '東京')

console.log(reserve1)
console.log(reserve2)