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

Feature request: User-defined type assertions #6052

Open
abonander opened this issue Mar 27, 2018 · 2 comments
Open

Feature request: User-defined type assertions #6052

abonander opened this issue Mar 27, 2018 · 2 comments

Comments

@abonander
Copy link

abonander commented Mar 27, 2018

In our Flow projects we're employing a fail-fast approach during development but fail-safe approach in production by having asserts that throw with a debug flag but simply log when that flag is off:

function debugAssert(cond: boolean, msg: string) {
    if (!cond) {
        if(global.debug_assertions) throw new Error(msg);
        else global.log.error(msg);
    }
}

We'd like to use this assert in type refinement, e.g. debugAssert(typeof someVal === 'string', 'value was not string') but Flow doesn't recognize it as a predicate since it doesn't return a boolean; even if it did, Flow doesn't like it because it's nontrivial. However, it does divert control flow when we want it to, so it would serve the same purpose.

I should note that even if we always threw an error on assertion failure, Flow still wouldn't recognize it as a predicate function because it doesn't return a boolean.

@stereobooster
Copy link

You can do something like this

(someVal:string)
debugAssert(typeof someVal === 'string', 'value was not string')

or write specific function

const assertString = (val: string, msg: string) => debugAssert(typeof someVal === 'string', msg);
assertString(someVal, 'value was not string');

@gnprice
Copy link
Contributor

gnprice commented Dec 2, 2020

Flow supports this use case -- the way you get it is to name the function invariant. See discussion at #646 and #989.

Quoting @samwgoldman at #989 (comment):

In fact, something very much like this is already supported. Facebook uses an invariant function, which is part of fbjs, but you can also use a NPM package, which someone helpfully extracted from React.

You can also use any other implementation you like, including the one in this issue report; there's just the one requirement that it has to be named invariant, rather than debugAssert or any other name. It'd sure be cleaner if there were a nice language syntax to declare that a function should be treated this way; but in practice, I think just renaming it to invariant is not too bad.

The big gap is just that this feature isn't documented (unless you count these issue threads 🙃.) It'd be great for it to gain a small bit of documentation.

Probably a good place for documentation of this would be as a small new section on the Type Refinements page... with perhaps a see-also link from the discussion of predicate functions. (For that matter, even independent of this invariant feature, it'd probably be helpful for the predicate-functions section to link to the type-refinements page, and vice versa.)

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

4 participants