facebook / flow

Adds static typing to JavaScript to improve developer productivity and code quality.
https://flow.org/
MIT License
22.07k stars 1.85k forks source link

%checks type refinement function for opaque alias types #5563

Open lll000111 opened 6 years ago

lll000111 commented 6 years ago

I'm using opaque alias types described here: https://flow.org/en/docs/types/opaque-types/

I'm also using the undocumented checks% hack to define type refinement functions, for example

declare function isHash(x: mixed): boolean %checks(typeof x === "string");

and the actual function is defined as

function isHash (thing: mixed): boolean {
    return typeof thing === 'string' && StorageBaseCommon.CRYPTO_HASH_RE.test(thing);
}

(I have a reason for using a separate declare statement to have the %checks on instead of putting it right on the actual function, but that's not important now.)

My problem is that I don't seem to have a way to write a type refinement function for an opaque alias type?

For example, I use SHA-256 hashes in my code, which are strings, but very special strings (obviously). So I'm using an alias

export opaque type SHA256Hash: string = string;




It's very unfortunate that I can't just tell Flow that a function checks a given type, that I can only use typeof and instanceof. That only works for "fake OOP" class-based programming where instanceof works. It doesn't work for a functional style when I have just different kinds of plain objects and no inheritance and nothing is constructed using new. And plain types cannot be aliased if only typeof is allowed for refinement.

panagosg7 commented 6 years ago

There are some limitations with refinements on opaque types:

This issue is not really related to the %checks functionality, though the limitations apply there as well.