0xf

日記だよ

関数の戻り値型の記述でジェネリクス型を利用すると unknown が出がち

特に理由もきちんと追えてないけど、ハマったやつもう一つ。最初 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 } のサブタイプなのだからより詳細な型が許される。つまり・・・

つまりどういうことだってばよ?(ここまで考えてあとは夜)