-
Notifications
You must be signed in to change notification settings - Fork 11
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
Add flow types generation, fix flow types #207
Conversation
scripts/generateFlowTypes.js
Outdated
import type { ComponentType, ElementConfig, Node, Component } from 'react'; | ||
|
||
declare module '@wework-dev/plasma' { | ||
declare type Data = { key: string, value: string }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be a { [key: string]: string }
?
} | ||
value: Object, | ||
}, | ||
}, | ||
|}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a mock (and roundabout) definition of SyntheticEvent<T>
name: string, | ||
onChange: () => mixed, | ||
onChange: (event: SyntheticEvent<HTMLInputElement>) => mixed, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest evt
. I think event
should be considered a saved word.
onBlur: (event: { target: {value: Object} }) => void, | ||
onChange: (event: { target: {value: Object} }) => void, | ||
onBlur?: (event: { target: { value: Object } }) => void, | ||
onChange?: (event: { target: { value: Object } }) => void, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SyntheticEvent
s?
|}; | ||
|
||
class TimePicker extends Component<Props> { | ||
static displayName = 'Plasma@TimePicker'; | ||
|
||
handleBlur = (event: { target: {value: Object} }): void => { | ||
handleBlur = (event: { target: { value: Object } }): void => { | ||
const newTime = event.target.value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should also be corrected to event.currentTarget.value
for Flow support.
.replace('<propTypes>', '<Object>')} | ||
|
||
declare export class CountedTextInput extends React$Component<{ ...$PropertyType<TextInput, 'props'>, counterStyle: string }> { } | ||
declare export class CountedTextArea extends React$Component<{ ...$PropertyType<TextArea, 'props'>, counterStyle: string }> { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideally we would generate decorated components automatically
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@GeReV maybe instead of parsing all type files under src/components, I should go over index.js, see which components are exported, find their paths, and extract types from them?
declare export class CountedTextInput extends React$Component<{ ...$PropertyType<TextInput, 'props'>, counterStyle: string }> { } | ||
declare export class CountedTextArea extends React$Component<{ ...$PropertyType<TextArea, 'props'>, counterStyle: string }> { } | ||
|
||
declare export var LocationPin: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we automatically export all files under icons as strings?
@kangax, sounds good with either approach. |
Even though flow has
gen-flow-files
command, it's experimental and doesn't really work — facebook/flow#5871People are using various workarounds for generating lib types — https://blog.kentcdodds.com/distributing-flow-type-definitions-for-node-and-browser-modules-3952ad38b357
One of the solutions is to create
.flow
files that are simply a copy of plasma source files. This increases npm package size significantly, and that might have been fine except that it doesn't really work. We bundle plasma into a single file and Flow doesn't know which modules are exported and how to annotate them.What I've decided to do for now is to automatically generate flow-typed defs in plasma and use that in SS. This is generally what a lot of libraries do (react-redux, lodash, etc.)
My solution has issues though. I'm extracting types from all the .jsx files under src/ using jscodeshift (same util that's used in codemods). The classes are exported and the types that those classes might use (e.g.
Tab
,Item
) are declared locally.One of the issues is that references like[update: now fixed]ExternalSelect.propTypes
are not currently resolved into proper types. For now, I replace them withObject
but there might be a way to do it properly.Similarly, we need to do something about[update: now fixed]typeof some_var
— those need to be resolved properly and substituted.Finally, all the types and classes are exported in the same scope so there's a chance of conflicts. I'm not sure what the best solution for this is; we could scope-rename the types (e.g.
type Item
fromtabs.jsx
becomestype tabs_Item
) and replace all occurrences in types.typeof ...
referencesUpdate: we might be able to use
flow type-at-pos
to resolve types with all the values