hegel icon indicating copy to clipboard operation
hegel copied to clipboard

Inference doesn't work if a method returns an instance of the class that is instantiated with the method's type parameters

Open eilvelia opened this issue 5 years ago • 3 comments

The type inference doesn't seem to work when a method returns an instance of the class whose type parameter depends on the method's type parameters. E.g:

class Functor<T> {
  map<U>(f : T => U) : Functor<U> { return new Functor<U>() }
}

const f1 = new Functor<number>()
const f2 = f1.map((x : number) : string => String(x)) // error

This errors with

Could not deduce type "Functor<string>" arising from the arguments (number) => string.
Please, provide type parameters for the call or provide default type value for parameters
of "<U>((number) => U) => Functor<U>" function.

It works correctly in Flow and TypeScript.

Can be fixed if f1.map<string>( is written manually.

Interestingly, if I replace

  map<U>(f : T => U) : Functor<U> { return new Functor<U>() }

with

  map<U>(f : T => U) { return new Functor<U>() }

then it will work, even though the inferred return type of map is still Functor<U>.

try hegel

eilvelia avatar Sep 12 '20 15:09 eilvelia

A similar (not the same though) thing happens if we try to change a class generic based on method's type parameters;

class HttpRequest<D = unknown> {
  data: unknown = null;

  setData<T>(data: T): HttpRequest<T> {
    this.data = data;
    return this;
  }
}

const req = new HttpRequest();

const result = req.setData(5);

Here, result's type is unknown where we would expect it to be number. I'm not sure if this is related as there is no error thrown but the inference is off, we can create an additional issue if that'd be more appropriate.

anacierdem avatar Aug 13 '21 06:08 anacierdem

Oh, right, it's another bug, related to inferencing this type. Thank you a lot guys (@anacierdem and @Bannerets) for providing this information.

JSMonk avatar Aug 13 '21 08:08 JSMonk

Also, seems like all bugs like this will be fixed in the second version of Hegel.

JSMonk avatar Aug 13 '21 08:08 JSMonk