特に理由もきちんと追えてないけど、ハマったやつもう一つ。最初 async function と Promise の固有の挙動かなと思ったけどそうではなかった。
// これは期待通り Rが推論される function sample<P, R, F extends (params: P) => { result: R }>(f: F, params: P) : R { return f(params).result } // 戻り値の型 R は unknown に推論される async function sample<P, R, F extends (params: P) => { result: R }>(f: F, params: P) : Promise<R> { return f(params).result } // これも R が unknown となる function sample<P, R, F extends (params: P) => { result: R }>(f: F, params: P) : Array<R> { return [f(params).result,] }
最初のやつの記述方針でうまくいったので後者に拡張して敗北したというメモです。
function getArray<T>(f: T): Array<T> { return [f,] }
みたいなのはそのまま推論される。
Promise<BaseType>
から見て Promise<SubType>
はサブタイプではない。F
は (params: P) => { result: R }
のサブタイプなのだからより詳細な型が許される。つまり・・・
つまりどういうことだってばよ?(ここまで考えてあとは夜)