Initial support for $ReadOnlyArray
Any-casting seems problematic with Object.freeze
IssueHunt Summary
Referenced issues
This pull request has been submitted to:
IssueHunt has been backed by the following sponsors. Become a sponsor
I skimmed the code...just realized, there's probably not a clean way to throw a runtime error if a $ReadOnlyArray is modified, is there? Seems like you're using Object.freeze to prevent the array from being modified, and I was thinking about using Proxies to throw errors but I assume there's not really a way to replace runtime references to the array with a Proxy object...
On second thought though, could statements like const foo: $ReadOnlyArray<X> = someArray be converted by babel-plugin-flow-runtime to const foo = wrapReadOnlyArray(someArray)?
@jedwards1211 what about casting to any? It should basically unfreeze array which is impossible to do, that's why I'm having concern with it
Ok, I see that any doesn't do anything to functions, so this is not a problem for $ReadOnlyArray.
There's also warning mode that only shows warning which is definitely no to Object.freeze
Oh, it can trace assignments with Babel?
var foo: string;
foo = 1;
was converted to
import t from "flow-runtime";
var _fooType = t.string(),
foo;
foo = _fooType.assert(1);
Right you can look up where an identifier was declared using path.scope.getBinding(identifier.name)
@jedwards1211 can I check what type annotation it has? This would work for $ReadOnlyArray or $ReadOnly, but wouldn't work for covariant properties
Also I think flow-runtime supports multiple files (imports), so not sure about this too
Yes, the binding identifier will have a type annotation node attached if the identifier is annotated, here is an example of what that looks like in the AST:

@gajus what would you think about just using the same runtime type as Array for the time being (until one of us gets around to inserting a check before any statements that mutate the array, if that ever happens?)
Sounds acceptable.
@goodmind I was thinking about this again because I use a lot of readonly types nowadays. It wouldn't actually make sense to insert any runtime checks for modifications on readonly-typed expressions, because such code paths would always throw (it's never in the developer's interest to write such a code path). For that reason it's really better to just rely on Flow to catch such cases, and not do anything special with the read-only status in babel-plugin-flow-runtime.