Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to restrict type of this for a particular method? #1369

Closed
rpominov opened this issue Feb 5, 2016 · 5 comments
Closed

Is it possible to restrict type of this for a particular method? #1369

rpominov opened this issue Feb 5, 2016 · 5 comments

Comments

@rpominov
Copy link

rpominov commented Feb 5, 2016

class Foo<T> {
  _x: T;

  constructor( x:T ) {
    this._x = x
  }

  // this method works with any instance of Foo
  getX(): T {
    return this._x
  }

  // this method works only with Foo<number>
  getXMultBy( y:number ): number {

    // this will result in "T. This type is incompatible with number", 
    // but let's ignore that for the sake of example
    return this._x * y
  }
} 

In this example, can we somehow add a restriction for getXMultBy that this must be an instance of Foo<number>, so the following code wouldn't type check?

(new Foo('bar')).getXMultBy(10)
@leonardfactory
Copy link

I don't know if you could do this in your project, however I think you should use inheritance here, like:

/* @flow */
class Foo<T> {
  _x: T;

  constructor(x: T) {
    this._x = x;
  }

  getX(): T {
    return this._x;
  }
}

class FooBar extends Foo<number> {
  constructor(x: number) {
    super(x);
  }

  getXMultBy(y: number) {
    return this._x * y;
  }
}

(new Foo('bar')).getX(); // ok
(new FooBar(12)).getXMultBy(10); // ok
(new Foo(12)).getXMultBy(10); // error!

If this is not feasible, you could try using invariant

@rpominov
Copy link
Author

rpominov commented Feb 5, 2016

@leonardfactory Yeah, inheritance isn't very convenient in my case. Invariant also will work, but only at run time...

Some context: in Fantasy Land some methods (like ap or sequence) work only when wrapped value has a certain type (ap needs it to be a function, and sequence needs it to be an Applicative). fantasyland/fantasy-land#50 (comment)

Inheritance indeed may be the right choice for this problem. Still I'm not sure it will be practical to use separate classes for some methods in FL code. This is not well explored though, and I'm not sure in either case.

Anyway what I originally asked may be useful in some cases, IMO. Would be cool if it was considered, or maybe already possible somehow.

@rpominov
Copy link
Author

rpominov commented Feb 5, 2016

What I'm trying to say is that, if we forget about Classes for a moment, this for methods basically just another argument, would be cool to be able to add type restrictions for that argument per each method.

@rpominov
Copy link
Author

rpominov commented Apr 8, 2016

Related: #452

@calebmer
Copy link
Contributor

We recommend either using inheritance or type guards/invariants for cases like this. The method will be on your class at runtime no matter what T is, so an invariant makes sense if you do not want to use inheritance 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants