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

Cleaning up the environment #666

Closed
popham opened this issue Jul 27, 2015 · 3 comments
Closed

Cleaning up the environment #666

popham opened this issue Jul 27, 2015 · 3 comments

Comments

@popham
Copy link
Contributor

popham commented Jul 27, 2015

For some time, I've been fantasizing about a --env flag for Flow to constrain the environment. My thoughts were centered on browser, node, browser,node. But that ignores #31, #396, and #615 (comment). It sounds like a few people are interested in overriding and/or extending standard libraries, and that should be a common use case. How about the following pull-version of declare?

import type { Node, Browser } from "flowLib"; // See hypothetical `flowLib.js` below

// Sugar for `declare var XMLHttpRequest: Browser.XMLHttpRequest`.
declare { XMLHttpRequest } from Browser; 

// Sugar for `declare var k: Node.k` for all export-k's in Node.
declare * from Node;

// Augment the module scope with a goofy `window`.
declare var window: Browser.window & {
  Buffer: Node.Buffer,
  WebSocket: Browser.WebSocket
};
  • The status quo fits into this schematic as import type { Node, Browser } from "flowLib"; declare * from Node; declare * from Browser; (and a configuration file option to evaluate a preamble before every file, but that would be the beginning of per-library .flowconfig's [one handy use for Flow could be to validate a bunch of code against an environment spec, so I want to provide a project-wide environment, so per-library .flowconfig's are a bad idea]).
  • Users on IE6, for instance, could reuse lots of cross-compatible stuff without (1) editing library files nor (2) excluding library files (--no-flowlib) and starting from scratch.
  • This would require module-scoped declares below the .flowconfig root.

Any thoughts on "fixing" this (foul smelling environment) before 1.0? (I never really looked much at TypeScript, and I realize that cross-compatibility with TS is kind of a project goal, so I apologize if I just suggested abandoning that goal.)

Hypothetical flowLib.js:

type window = {
  WebSocket: class Ws {
    /*
     * I'm currently working on a straw man that uses this
     * syntax for interfaces.  Sorry if it looks goofy--it looks
     * perfectly natural to me now.
     */
    constructor(): void;
  },
  XMLHttpRequest: class {
    constructor(): void;
  }
};

export type Browser = window & { window };

export type Node = {
  Buffer: class {
    constructor(): void;
  }
}
@nmn
Copy link
Contributor

nmn commented Jul 28, 2015

+1

This seems like a great idea. I think a couple of additions would make this even better.

One area where Typescript is way ahead of Flow is in type definition files. However, Typescript has it's own package manager for type definitions and I think Flow can do an even better job by piggy-backing on top on NPM itself.

The only hard dependency for that to work is supporting type imports in comments:

/* import type { Node, Browser } from "flowLib"; // See hypothetical `flowLib.js` below */

// Sugar for `declare var XMLHttpRequest: Browser.XMLHttpRequest`.
/* declare { XMLHttpRequest } from Browser;  */

// Sugar for `declare var k: Node.k` for all export-k's in Node.
/* declare * from Node; */

// Augment the module scope with a goofy `window`.
/* declare var window: Browser.window & {
  Buffer: Node.Buffer,
  WebSocket: Browser.WebSocket
}; */

This, or something like this should be legal in flow as, type annotations in comments are already supported:

var x /*:number*/ = 5

Allowing comments for type would allow library authors to add a build step where all the type annotations are put in comments instead of being stripped out. Hence, whenever you import a package, you'd get it's type definitions for free.

Of course, if the library author writes a complete separate type definition file, the usual flow would be:

import someModule from 'some-module'
declare * from 'some-module/types'

By allowing type imports in comments, the library author could import the type definition in the library itself, and end-users of the library wouldn't need to import the type definition separately.

@mroch
Copy link
Contributor

mroch commented Jul 29, 2015

@nmn I think /*:: is what you're looking for (see http://flowtype.org/blog/2015/02/20/Flow-Comments.html#2)

@nmn
Copy link
Contributor

nmn commented Jul 29, 2015

@mroch Holy shit that is amazing. How did I not notice that! I've gotten into flow seriously recently and it has helped catch a ton of subtle bugs.

I'll start adding it to my OSS projects as well now!

@popham popham closed this as completed Jun 7, 2016
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