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

Document advanced Utility Types #2464

Closed
17 of 20 tasks
gabro opened this issue Sep 14, 2016 · 58 comments
Closed
17 of 20 tasks

Document advanced Utility Types #2464

gabro opened this issue Sep 14, 2016 · 58 comments

Comments

@gabro
Copy link
Contributor

gabro commented Sep 14, 2016

In the process of learning Flow and adopting it at work, I've often needed "advanced" operators that are completely missing from the documentation.

So far I relied on this blog post (now slightly outdated) http://sitr.us/2015/05/31/advanced-features-in-flow.html and code found in the Flow and React codebases.

I think I'd be nice to have this features explained in the official documentation.

The features I'd like to see documented are:

And maybe (they look like internal features though):

Am I missing something?

In order to get the ball rolling, I've sketched a documentation page for "dynamic" enums using $Keys (aka $Enum). I have a PR almost ready that I will submit soon.

Is this something that you guys are already working on?
I'd be glad to help (provided that I understand the features first 😅).

Let me know!

@gabro
Copy link
Contributor Author

gabro commented Sep 14, 2016

PR submitted, feedbacks are very welcome!

@anmonteiro
Copy link
Contributor

anmonteiro commented Sep 16, 2016

@gabro I think $Exact is also missing docs, as well as its literal ({| |}) notation?

@gabro
Copy link
Contributor Author

gabro commented Sep 16, 2016

@anmonteiro yes, it's on my radar but I didn't include it there as I wasn't sure $Exact is an internal-only representation of {| |} or not. Along the same lines, we could also document $All $Either and similar utility types that have an ad-hoc syntactic sugar.

Long story short, are $Exact, $All, $Either (and others?) also intended for client's use, or are they just internal representations? This is a question for the Flow team, though. /cc @mroch @thejameskyle

@gabro
Copy link
Contributor Author

gabro commented Sep 16, 2016

@anmonteiro about the documentation for {| |}, yes, it's missing, although I'm not sure it would fit this issue, which is about "advanced" features, named "Utility Types" in the first related PR. Maybe we should open another issue?

@anmonteiro
Copy link
Contributor

@gabro IMO I agree it's a different concern so another issue is necessary. I should have clarified my initial intent, which was to bring up the fact that it wasn't documented, not to include in a PR for this one.

@STRML
Copy link
Contributor

STRML commented Sep 21, 2016

Can anyone elaborate on usage of $Abstract? We were subclassing React.Component and had a surprising number of bugs disappear (and new, good type errors) once I realized the builtin uses $Abstract<State> and $Abstract<DefaultProps>.

@gabro
Copy link
Contributor Author

gabro commented Sep 21, 2016

@STRML from what I was able to "reverse engineer", it looks like $Abstract imposes a constraint on a subclass, forcing it to provide that field. Here's a few examples that helped me clarifying the concept:

class MyAbstract<T> {
  foo: $Abstract<T>
}

class MyConcrete extends MyAbstract<string> {} // error, foo is missing
class MyConcrete2 extends MyAbstract<string> {
  foo = 'bar' // ok
}
class MyConcrete3 extends MyAbstract<string> {
  foo = 42 // error, foo must be a string
}

class MyAbstract2<T> {
  foo: T
}
class MyConcrete4 extends MyAbstract2<string> {} // no problemo

From the examples above, the most notable difference between T and $Abstract<T> is that the former allows for a missing field, whereas the latter requires the subclass to provide it.

I would love if anyone from the Flow team could confirm my "hypothesis" (so that we can document this!)

@STRML
Copy link
Contributor

STRML commented Sep 21, 2016

Interesting insight. It's odd, though, that you're not required to actually define static defaultProps or state when extending React.Component.

@gabro
Copy link
Contributor Author

gabro commented Sep 21, 2016

@STRML I think you are required to, if you specify a type for it. Meaning

class MyComponent extends React.Component { } // ok
class MyComponent extends React.Component<{ x: string }, any, any> { } // error
class MyComponent extends React.Component<{ x: string  }, any, any> {
  static defaultProps = { x: 'foo' };
} // ok

Here's some example from the tests: https://github.com/facebook/flow/blob/master/tests/new_react/bad_default_props.js

@STRML
Copy link
Contributor

STRML commented Sep 21, 2016

Gotcha. So if you just don't specify the type parameters at all, there isn't a difference? Strange.

Still, I wonder why updating our React.Component extension to use $Abstract<DefaultProps> and $Abstract<State> (from non-$Abstract versions) uncovered so many previously-ignored type errors. There must be more to it.

@gabro
Copy link
Contributor Author

gabro commented Sep 21, 2016

So if you just don't specify the type parameters at all, there isn't a difference?

I think as long as the type is unbound anything is accepted, including void, i.e. missing.

But again, I'm just guessing here. Either I'll learn some OCaml and start reading the source code, or someone from the Flow team can shed some light! 😄

@gabro
Copy link
Contributor Author

gabro commented Sep 21, 2016

Just to clarify my void point before:

class MyAbstract<T> {
  foo: $Abstract<T>
}

class MyConcrete extends MyAbstract<void> {} // ok!

@gabro
Copy link
Contributor Author

gabro commented Sep 25, 2016

@anmonteiro I just opened a new issue for tracking the {| |} documentation. Refer to #2524

@gabro
Copy link
Contributor Author

gabro commented Oct 1, 2016

Adding $ObjMap to the list. I really can't wait for #2465 to be merged, so that we have a scaffold to work on!

@STRML
Copy link
Contributor

STRML commented Oct 6, 2016

Re: $Pred/$Refine, found this:

  $Pred<N> is an "abstract predicate type", i.e. denotes a (function) type that
  refines N variables. So if `cb` is a function, then it should be refining
  exactly N argument. It is abstract in that we do not need to specify:
  (a) which variables are going to be refined (just the number), or (b) what
  exactly the refinement (predicate) is going to be.

  $Refine<T,P,k> is a refinement type, that refines type T with the k-th
  argument that gets refined by an abstract preficate type P.

facebook-github-bot pushed a commit that referenced this issue Nov 10, 2016
Summary:
Ref #2464

This PR adds documentation for writing enums in Flow, both using literal types as enum keys and using the `$Keys` operator to generate an enum from a literal object.

I'm not sure whether the structure is appropriate (I just added a new chapter to the reference documentation), but I'd love some feedback!
Closes #2465

Differential Revision: D3868308

Pulled By: thejameskyle

fbshipit-source-id: 105ceed93d1810d33199f0f743527201f0606556
facebook-github-bot pushed a commit that referenced this issue Dec 1, 2016
Summary:
Ref #2464

This PR documents the `$Diff` utility type, explaining how it is used in React to define the type of the props accepted by a Component.
Closes #2472

Reviewed By: samwgoldman

Differential Revision: D4168072

Pulled By: gabelevi

fbshipit-source-id: 62bde7da0940bf694f64f37bd5724c536627caff
@STRML
Copy link
Contributor

STRML commented Dec 8, 2016

@andreypopp Could you provide any information on $ObjMap, since it appears you've used it in validated? I've had no luck figuring it out so far.

Edit: Got something going, it appears this doesn't throw an error if you rebind the var (so mirrored.bar = 'foo' is legal, but casting it to a different literal is not). It's definitely fiddly to use.

@gcanti
Copy link

gcanti commented Dec 8, 2016

@STRML some infos here #2674

@cqfd
Copy link
Contributor

cqfd commented Jan 24, 2017

Another +1 for documentation for $ObjMap and $TupleMap. They're super cool and I wish I had found out about them sooner!

I think a nice motivating example would be Flow's type for Promise.all:

static all<Elem, T:Iterable<Elem>>(promises: T): Promise<$TupleMap<T, typeof $await>>;
declare function $await<T>(p: Promise<T> | T): T;

You could then use $ObjMap to type something like Bluebird's Promise.props (basically all but for an object of promises):

static props<Elem, T: { [prop: string]: Elem }>(promises: T): Promise<$ObjMap<T, typeof $await>>;

@STRML
Copy link
Contributor

STRML commented Jan 25, 2017

Hoping the core team will place more importance on this. I understand some of these features are subject to change, but the community could help shape their development.

@STRML
Copy link
Contributor

STRML commented Jan 25, 2017

That's appreciated, but largely incomplete, especially compared to the post from 2015.

@STRML
Copy link
Contributor

STRML commented Jan 25, 2017

That particular one is actually in the OP. But yes, there is a lot of missing information. I have a PR open but it has not gotten any attention.

@julienw
Copy link
Contributor

julienw commented Dec 13, 2017

The doc about utility types has just been updated => https://flow.org/en/docs/types/utilities/
We still miss some like Shape.

@LoganBarnett
Copy link

@villesau blugh that was pretty careless of me to miss that. Thanks for catching it!

@gabro it's much appreciated that you're keeping the ticket up to date though. I imagine any kind of bookkeeping we do immensely helps people when they can function as active maintainers. To the @villesau's point above, $SubType and $SuperType are documented with the exact text "Work in Progress" which is kind of like the honorable mention equivalent of documentation. Can we uncheck those two boxes please?

@gabro
Copy link
Contributor Author

gabro commented Dec 13, 2017

@LoganBarnett sure, done!

@zen0wu
Copy link

zen0wu commented Jan 15, 2018

It seems that $Abstract utility type is removed, so we're back to square one on this topic!

@bitpit
Copy link

bitpit commented Feb 14, 2018

Man this is disheartening coming from typescript

@lll000111
Copy link
Contributor

lll000111 commented Mar 9, 2018

@bitpit It's worse when you compare the issues lists of both TypeScript and of Flow. One of those two projects gets issues closed, the other one just collects them.... (not that the list of open issues is any shorter though) and we Flow users are mostly talking among ourselves here in the issues comments. I filed only one issue for TypeScript and had Anders Hejlsberg himself reply to it, and it was not an especially noteworthy issue at all.

@zen0wu
Copy link

zen0wu commented Mar 10, 2018

@lll000111 I had a lot of TODO (flow/#xxxx) in my codebase, but this one is my favorite.
Context: This is the type for the stack in componentDidCatch feature in React 16.

// TODO (flow/#5139): It's pretty lame that TypeScript has the stubbed type but not flow itself
type ReactErrorInfo = {
  componentStack: string,
};

@forticulous
Copy link

Since I didn't see it anywhere, we should add $NonMaybeType to the list of undocumented advanced types

@mrkev
Copy link
Contributor

mrkev commented May 3, 2018

Done 👍

@sibelius
Copy link

should we document $Pred and $Refine as well?

@jamesisaac
Copy link
Contributor

Nearly all of these are documented (or deprecated) now, mostly under Utility Types, but I've added links to the original list anyway for reference.

$ObjMapi has a PR waiting, so it looks like all that's left is $Compose, $ComposeReverse and $CharSet.

$Pred, $Refine and $Exports do sound like they're internal types not meant for public use -- maybe someone on the Flow team could confirm? cc @nmote @jbrown215

@jamesisaac jamesisaac changed the title Document advanced features Document advanced Utility Types Mar 8, 2019
@nmote
Copy link
Contributor

nmote commented Mar 8, 2019

$Pred, $Refine and $Exports do sound like they're internal types

Honestly, I'm not even sure what these do, so my guess is yes. Maybe @panagosg7 could weigh in (looks like he authored the file that you linked)

@bradennapier
Copy link

bradennapier commented Mar 8, 2019

I learned about $Pred and $Refine from https://medium.com/netscape/secret-flow-types-86b2ebb30951 then by reading the documentation in the actual code which I believe was fairly detailed. However, not sure I ever used it anywhere in the end - this was ages ago now heh :-P

Update: Not finding those comments in the codebase now :-D maybe i hallucinated them hah

@panagosg7
Copy link
Contributor

Indeed, $Pred and $Refine are purely experimental. They're mostly proof of concept for my internship project at the time. The API they expose has several holes that I haven't gotten to seal, since priorities have shifted since.

facebook-github-bot pushed a commit that referenced this issue Mar 26, 2019
Summary:
Ref #2464

This PR documents the $ObjMapi utility type.
Pull Request resolved: #5576

Reviewed By: gabelevi

Differential Revision: D14555190

Pulled By: panagosg7

fbshipit-source-id: 64891ca6486cc2ffea2d3fc96d1902a6a7f8ec4e
facebook-github-bot pushed a commit that referenced this issue Jul 22, 2019
Summary:
I added documentation for the previously undocumented utility function (see #2464)

To be honest, maybe we should consider deprecating `$Exports` because the `import typeof` feature is now supported and mentioned here: https://flow.org/en/docs/types/modules/
Pull Request resolved: #7945

Differential Revision: D16426558

fbshipit-source-id: 7bd3d2d4de6ad4acb229eebb75cf7faa984368fa
@gkz
Copy link
Member

gkz commented Mar 31, 2023

We don't plan on documenting the remaining 3 experimental types.

@gkz gkz closed this as completed Mar 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests