devexperts/remote-data-ts

sequenceS and sequenceT from fp-ts Apply gives type errors

Closed this issue · 11 comments

I'm not sure if this is an upstream bug in fp-ts, or if something is wrong with the implementation here.

I would expect sequenceS and sequenceT to work like they do for Either, but instead I get type errors.

import * as remoteData from "@devexperts/remote-data-ts/es6/remote-data";
import { apply, either } from "fp-ts/es6";

export const sequenceSEither = apply.sequenceS(either.either) // WORKS
export const sequenceSRemoteData = apply.sequenceS(remoteData.remoteData) // Error: No overload matches this call.
export const sequenceTEither = apply.sequenceT(either.either) // WORKS
export const sequenceTRemoteData = apply.sequenceT(remoteData.remoteData) // Error: No overload matches this call.

The full error in both cases is:

No overload matches this call.
  The last overload gave the following error.
    Argument of type 'Monad2<"RemoteData"> & Foldable2<"RemoteData"> & Traversable2<"RemoteData"> & Bifunctor2<"RemoteData"> & Alt2<"RemoteData"> & Extend2<...> & Alternative2<...>' is not assignable to parameter of type 'Apply<"RemoteData">'.
      Types of property 'ap' are incompatible.
        Type '<E, A, B>(fab: RemoteData<E, (a: A) => B>, fa: RemoteData<E, A>) => RemoteData<E, B>' is not assignable to type '<A, B>(fab: HKT<"RemoteData", (a: A) => B>, fa: HKT<"RemoteData", A>) => HKT<"RemoteData", B>'.
          Types of parameters 'fab' and 'fab' are incompatible.
            Type 'HKT<"RemoteData", (a: A) => B>' is not assignable to type 'RemoteData<unknown, (a: unknown) => unknown>'.
              Type 'HKT<"RemoteData", (a: A) => B>' is missing the following properties from type 'RemoteSuccess<(a: unknown) => unknown>': _tag, valuets(2769)
Apply.d.ts(292, 25): The last overload is declared here.

Here is a more elaborate codesandbox demonstrating the problem:

Looks like smth in fp-ts changed... I have no error in remote-data master branch, but I do have this error in fp-ts master branch. Need to investigate, thanks for the report!

Side project:
fp-ts@2.5.3 - no error
fp-ts@2.6.6 - error

Separate project:
fp-ts@2.5.3 - no error
fp-ts@2.6.6 - error

That's interesting. The project where I discovered this problem is still on fp-ts@2.5.3. And if I change to that version in the codesandbox, I still get the error 🤔

Codesandbox with fp-ts@2.5.3

@larskinn could you check npm ls fp-ts or yarn why fp-ts? Is it possible you have 2 versions of fp-ts installed so that remote-data and apply reference different HKT dictionaries?

could you check npm ls fp-ts or yarn why fp-ts? Is it possible you have 2 versions of fp-ts installed so that remote-data and apply reference different HKT dictionaries?

It does not seem like that's the case.

$ npm ls fp-ts
<projectname>@1.0.0 C:\code\<path>\reactapp
+-- @devexperts/remote-data-ts@2.0.3
| `-- fp-ts@2.5.3  deduped
+-- @<my-employers-namespace>/react-components@3.0.1
| `-- fp-ts@2.5.3  deduped
`-- fp-ts@2.5.3

Yeah, looks so, I also have a single version installed.
Well, the problem is even simpler, HKT constraints do not accept RemoteData URI:

import { Apply2 } from 'fp-ts/lib/Apply';
import { remoteData, URI } from '@devexperts/remote-data-ts';
const tmp: Apply2<URI> = remoteData;
//                ^-- error!

Usually it's because of 2 versions of fp-ts installed (2 different dictionaries) but it's not the case now.
The problem goes away if we manually redeclare module augmentation:

import { RemoteData } from '@devexperts/remote-data-ts';
declare module 'fp-ts/lib/HKT' {
	interface URItoKind2<E, A> {
		readonly [URI]: RemoteData<E, A>;
	}
}

This may be used as a temporary quickfix.
But this is very weird since we only use a single global URItoKind2 dictionary.
/cc @gcanti could you please take a look? Am I missing something in fp-ts@2.6.6?

import { Apply2 } from 'fp-ts/lib/Apply';
import { remoteData, URI } from '@devexperts/remote-data-ts';
const tmp: Apply2<URI> = remoteData;
//                ^-- error!

I actually don't get this error, tried with @devexperts/remote-data-ts@2.0.3 and fp-ts@2.5.3, 2.6.5 and 2.6.6

@raveclassic not sure what's going on, I encountered this weird thing once but I coundn't repro

@raveclassic re: the URI error, here's another codesandbox, and I can't reproduce it. As mentioned I tried with different fp-ts versions.

I'm far out of my depth re: the actual type class implementations, so I can't be much help there. But let me know if there's anything else I can do to narrow down the issue.

The problem goes away if we manually redeclare module augmentation:

import { RemoteData } from '@devexperts/remote-data-ts';
declare module 'fp-ts/lib/HKT' {
	interface URItoKind2<E, A> {
		readonly [URI]: RemoteData<E, A>;
	}
}

I was trying to add this to my local branch, and it did not fix the problem. But while trying it out in the codesandbox mentioned above, I discovered this interesting fact:

If I import apply and either directly from fp-ts instead of fp-ts/es6, the type errors go away! (without the above redeclaration hack)

I also see that @devexperts/remote-data-ts/es6/remote-data only imports from fp-ts/lib/... and not fp-ts/es6/..., ref #46

Is it possible that for instance fp-ts/es6/Apply is incompatible with fp-ts/lib/Apply somehow?

The initial reported problem with sequenceS and sequenceT goes away when the es6 output imports from fp-ts/es6. I made a PR.