Looking at the Ramda documentation for transduce, there are two examples given, each of which cause the Typescript compiler to throw a different error.
Example 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 throws the following exception for 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'.
If I change flip(append)
to flip(append) as any
the code works as expected.
Example 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 throws the following exception for 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.
Same as above, if I change firstOddTransducer
to firstOddTransducer as any
the code works as expected.
First, what do these particular errors even mean?
Second, what is the best way to deal with these sorts of issues with functional typescript? So often, when looking at various learning resources for typescript, users are warned against using any
or against using // @ts-ignore
as if it something you should never do, but the more complex my codebase gets, and the more functional my programming style becomes, the more of these seaming incomprehensible errors messages I receive for perfectly acceptable code. I don't mind spending a little bit of my time to make the types better, but I don't want to spend too much time debugging problems with types when I know the code is good.
Third, are there any tips that can help in situations when you're not quite sure if there is a problem with the types or with typescript, as above, or if there is a problem with the javascript code, e.g., techniques for determining where the actual problem is so you can either investigate or ignore?