英語だと 'No overload matches this call' って言われると思う。タイトルが長い。
TS書いてて、関数の引数に Options
なオブジェクトを受け取って、そのオプションのプロパティによって返り値が違うという関数を書いていた(hoge関数とする)。
で、hoge関数を使いつつ、hoge関数が受け取れる引数の型を外部から渡せる関数(foo関数とする)を書いていた。←ここでタイトルのエラーで怒られてしまった。
コード
type A = { passNumber: number toReturnString?: undefined } type B = { passNumber: number toReturnString: true } type Options = A | B function hoge(options: A): number function hoge(options: B): string // function hoge(options: Options): string | number function hoge(options: Options) { if(options.toReturnString === true) { return options.passNumber.toString() } else { return options.passNumber } } // 普通に使う分には通る const willNumber = hoge({passNumber:1}) const willString = hoge({passNumber:1,toReturnString:true}) console.log('willNumber',willNumber) console.log('willString', willString) // 通らない!!!!!!!!!! function foo(options:Options) { return hoge(options) }
コードの解説
上記コードブロックのhoge関数は toReturnString
がoptionalで、trueだったら返り値がstring
になるし、そうじゃなかったらnumber
で返るという関数。
hoge関数をだけで使う分には通るのだけど、foo関数でhoge関数にargmentsで受け取ったオプションの同じ型を渡すとエラーになる(L33)。
答え
上記TS playgroundのL15のコメントアウト箇所を外せば通るようになる。
function hoge(options: Options): string | number
感想
オーバーロードのimplements(実装記述)で書いていれば通るものだと思っていたのでハマってしまった。
オーバーロードの対応する型パターンは全部記述しないといけないらしいという学びがあった。
最初、hoge関数単体で使えばコンパイル通るしちゃんと返り値が意図通りのオーバーロードの挙動をしてくれていたのでオーバーロード実装側に問題があると気づけなかった。foo関数の実装側でなにか凡ミスがあるのかとウンウン唸って時間を使ってしまった。