Ramda Transducers上的打字稿类型错误,以及如何处理良好代码上令人困惑的类型错误

问题描述 投票:1回答:1

查看Ramda文档中的transduce,有两个示例,每个示例都会导致Typescript编译器引发不同的错误。

示例1:

test('ex. 1', () => {
  const numbers = [1, 2, 3, 4]

  const transducer = compose(
    map(add(1)),
    take(2)
  )

  const result = transduce(transducer, flip(append), [], numbers)

  expect(result).toEqual([2, 3])
})

Typescript为flip(append)引发以下异常:

Argument of type '(arg1: never[], arg0?: {} | undefined) => <T>(list: readonly T[]) => T[]' is not assignable to parameter of type '(acc: ({} | undefined)[], val: {} | undefined) => readonly ({} | undefined)[]'.
      Types of parameters 'arg1' and 'acc' are incompatible.
        Type '({} | undefined)[]' is not assignable to type 'never[]'.
          Type '{} | undefined' is not assignable to type 'never'.
            Type 'undefined' is not assignable to type 'never'.

如果将flip(append)更改为flip(append) as any,代码将按预期工作。

示例2:

test('ex. 2', () => {
  const isOdd = x => x % 2 === 1
  const firstOddTransducer = compose(
    filter(isOdd),
    take(1)
  )

  const result = transduce(
    firstOddTransducer,
    flip(append) as any,
    [],
    range(0, 100)
  )

  expect(result).toEqual([1])
})

Typescript为firstOddTransducer引发以下异常:

Argument of type '(x0: readonly any[]) => Dictionary<any>' is not assignable to parameter of type '(arg: any[]) => readonly any[]'.
      Type 'Dictionary<any>' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 16 more.

与上述相同,如果我将firstOddTransducer更改为firstOddTransducer as any,代码将按预期工作。

首先,这些特定错误甚至意味着什么?

其次,用功能性打字稿处理这类问题的最佳方法是什么?因此,经常在查看各种打字稿学习资源时,会警告用户不要使用any或不要使用// @ts-ignore,就像您永远不应该这样做一样,但是我的代码库变得越复杂,我的编程风格就越有用变得越来越多,我收到的关于完美可接受代码的更多无法理解的错误消息。我不介意花一些时间来改善类型,但是当我知道代码很好时,我不想花太多时间来调试类型问题。

[第三,当您不太确定类型或打字稿是否有问题(如上所述)或javascript代码是否有问题(例如,用于确定实际问题在哪里,以便您可以调查或忽略?

typescript ramda.js transducer
1个回答
0
投票

在撰写本文时,这是TypeScript的局限性,您根本无法表达必须从以后的使用中推断出类型的一部分。

直到调用transduce才真正绑定所有类型参数,所以,直到那时它才是完整类型,或者相反,TypeScript在完成该操作之前不知道如何完成类型。 TypeScript会尝试从上下文推断类型,所以也许,如果将所有内容放在一行中,它也许可以做到这一点(不是说会做到)。

从根本上说,传感器是序列/流/可观察值的抽象,当您实际对某些数据运行传感器时,可以向编译器授予此信息。这时需要绑定数据的类型信息。

我唯一想到的是,您必须将unknown用作数据的占位符类型,直到运行transduceinto。它不会授予您键入安全性,但是会抑制编译器警告,无论哪种方式都是误报。这不是完美的,但应该可以。

© www.soinside.com 2019 - 2024. All rights reserved.