-
Notifications
You must be signed in to change notification settings - Fork 43
Description
In Flow, the following declarations are equivalent:
type Y = number;
type X = {
y: Y;
}and
type X = {
y: Y;
}
type Y = number;This plugin translates the first one correctly, but in the second one
the attribute y of the PropTypes generated for X refers to Y as if
it were an external class, not a Flow type. In practice, this means that
the attribute is equivalent to y: any. Presumably, this is because the
conversion scans linearly across the file and has not yet encountered
the definition of Y.
This occurs frequently in practice. A structure like
export type CommitData = {
fileToCommits: {[filename: string]: string[]},
commits: {[commitHash: string]: Commit},
};
type Commit = {
author: string,
stats: {[filename: string]: FileStats},
};
type FileStats = {
lines: number,
added: number,
deleted: number,
};is perfectly readable, but is turned by this plugin into
var bpfrpt_proptype_CommitData = {
fileToCommits: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.string.isRequired).isRequired).isRequired,
commits: PropTypes.objectOf(function () {
return (typeof Commit === "function" ? PropTypes.instanceOf(Commit).isRequired : PropTypes.any.isRequired).apply(this, arguments);
}).isRequired
};
which is effectively useless because typeof Commit === "undefined" as
Commit does not exist in the code. To get the right structure, one
must permute the source:
type FileStats = {
lines: number,
added: number,
deleted: number,
};
type Commit = {
author: string,
stats: {[filename: string]: FileStats},
};
export type CommitData = {
fileToCommits: {[filename: string]: string[]},
commits: {[commitHash: string]: Commit},
};This is much less readable. The high-level concepts should come first
(why do I care about FileStats if I don’t know that I’m talking about
commits or commit data?). But even discarding claims of readability, the
plugin output is clearly doing the wrong thing: equivalent Flow programs
are being translated different, which shouldn’t be the case.