【问题标题】:Why can't typescript infer return type in compose type [duplicate]为什么打字稿不能在撰写类型中推断返回类型[重复]
【发布时间】:2021-10-19 14:24:39
【问题描述】:

我有一个选择函数,可以从对象中选择属性。显然我希望返回类型反映生成的新类型。

const getIdentifier = pick(['type', 'id'])
const result = getIdentifier(record)

// works as expected
const id = result.id
// is missing as expected
const name = result.attributes.name

但是一旦我在 compose 类型函数中使用该函数,它就不再推断它的类型:

const run = compose(
    // doesnt infer type, id constrain, why not???
    (identifier) => identifier,
    getIdentifier,
    // infers RecordJson
    (rec) => rec,
    getRecord
)

playground查看完整的类型和示例。

TypesScript 无法做到这一点吗?它能够做到吗?我有什么办法可以让它工作吗?

提前致谢!

【问题讨论】:

  • 你可以查看我关于打字撰写功能的文章catchts.com/FP-style#compose
  • 考虑使用 TS 4.5 这个方法,它允许你处理超过 10 个函数

标签: typescript


【解决方案1】:

typescript 不喜欢它必须通过首先查看函数的最后一个参数来解析泛型,它查看第一个参数,无法找出泛型,因此将其设置为 unknown 然后继续并且不会回溯。

如果您将 compose 编写为管道而不是函数组合,则它可以工作:

declare function composeA<Initial, A,B, Final>(f1: (a:Initial)=>A, f2: (b:A)=>B, f3: (c: B)=>Final): Final

interface A{
  a:{
    id: string,
    name: string,
    other: number
  }
}

declare function pick_id_and_name<T extends Record<"id"|"name", unknown>>(val:T): Pick<T, "id"|"name">
// this works perfectly
const getField = composeA(
  (data: A)=>data.a,
  pick_id_and_name,
  (stuff)=>[stuff.id, stuff.name]
)

declare function composeB<Initial, A,B, Final>(f3: (c: B)=>Final, f2: (b:A)=>B, f1: (a:Initial)=>A): Final
// this falls into the same error you are getting, `stuff` is unknown
const getField2 = composeB(
  (stuff)=>[stuff.id, stuff.name],
  pick_id_and_name,
  (data: A)=>data.a,
)

playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多