Flow: Missing Existential Type (`*`) deprecation explanation

Created on 16 May 2018  ·  19Comments  ·  Source: facebook/flow

I noticed that in 0.72 the Existential Type (*) is deprecated; seems like a good idea, but I think the following would be helpful for those attempting to upgrade:

  • [DEPRECATED] tag in the docs for Existential Type
  • An official explanation for _why_ it is deprecated
  • An upgrade guide for explaining alternatives to using *, with a few common-case examples

I'd be happy to contribute any of those ☝️, but don't know where to begin.

The only discussion I've been able to find in the repo is here: https://github.com/facebook/flow/commit/39968bcd1f5badccfd4303b2245a88203fa49377

/cc @avikchaudhuri Any guidance would be appreciated; thanks! 🙇

Needs docs

Most helpful comment

The * type was deprecated three months ago, and it's still not even mentioned in the docs. Can a project owner please shed some light on why it's deprecated (and whether it's really supposed to be deprecated in all situations, even in generics)?

All 19 comments

Also see #6294 -- while I agree with the project owners that "" may not be necessary the same cannot be said for its use in generic types. Sometimes all you care about is the parent type and not the subtype, in that case "" is (was) quite useful, a) because leaving out the subtype(s) shows the intent and b) sometimes the subtype definition may be quite long, and without "*" the only choice left is to repeat the original subtype definition.

Does flow print deprecation notices only in strict mode? Seems like a good idea to give developers heads up even in the loose mode. Using Flow v0.77 in loose mode and see no errors.

The * type was deprecated three months ago, and it's still not even mentioned in the docs. Can a project owner please shed some light on why it's deprecated (and whether it's really supposed to be deprecated in all situations, even in generics)?

TIL * is deprecated in Flow 🤦‍♂️

Is there any further info on this? Docs page still don't show any sign of deprecation nor explanation on what to do instead => https://flow.org/en/docs/types/utilities/#toc-existential-type

No update on this??

any interest in someone submitting a PR for this?

@vicapow for that we'd first need some more detailed insights as to _why_ it is deprecated and what the rationale behind it is. as far as i understood, i always perceived the type inference as one of flows explicit strengths.

I'm wondering this as well. Why's * deprecated since 0.72? What should we use in it's place? Generics?

@pbondoer it fall backs to any if it can't infer something

@goodmind

I know, that wasn't what I was asking. I know what * does and how it works, but I'm trying to understand what we should use in it's place, since it's been deprecated in 0.72.

It'd be nice to get an official response on this, the official documentation is still mentioning it without saying anything about it being deprecated, and 0.72 has been out for a year now.

@pbondoer [Disclaimer, this is just my understanding as someone who follows flow closely, I don't have any insider knowledge]

Generics can indeed be a good start. Or just writing the types manually. There's no global answer to "what should you write as an annotation of the function you exported?". In the last versions, flow expects more annotations than before (see the issues with generics at the boundaries of your modules). The existential types goes against this idea.

But as a flow user, I'm with you, this deprecation just happened out of nowhere, and * is still a nice escape hatch. But now I believe that it might actually just better write down an any, and admit that we don't know the type, than just hope that flow will get it.

Since * is deprecated, I'd love to see * replace any for opting out of the type checker. It's a single character, I'd imagine most people already associate * with regex wildcards for matching anything, and I think the code would be cleaner:

const map :Map<*, *> = new Map();
  vs
const map :Map<any, any> = new Map();
connect<*, *, *, *, *, *>(mapStateToProps)(Component);
  vs
connect<any, any, any, any, any, any>(mapStateToProps)(Component);

That strikes me as very dangerous, since * is deprecated but still functional in Flow (AFAIK at least), and plenty of people/codebases would still have lots of * sprinkled throughout. Turning all of them into anys suddenly would seem less than great.

Apologies, should have clarified. I didn't mean to imply a sudden switch, but a gradual transition spread over a few releases.

Just noting that it seems like _ is a substitute for some previous uses cases of * when it comes to generics. https://flow.org/en/docs/types/generics/#toc-supplying-type-arguments-to-callables

Is it naive to ask for an option that would run Flow, have it figure out what type was being used for each * usage, and then just put that inferred type into the source file directly? I.e. as a way of migrating off of *.

The docs for * have been updated as of https://github.com/facebook/flow/pull/7627, this can probably be closed.

Thanks for pointing this out @lyleunderwood and to all who contributed to the discussion!

Was this page helpful?
0 / 5 - 0 ratings