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

chore: fix flow types for overrides, popover #98

Merged
merged 3 commits into from
Jul 31, 2018
Merged

chore: fix flow types for overrides, popover #98

merged 3 commits into from
Jul 31, 2018

Conversation

schnerd
Copy link
Contributor

@schnerd schnerd commented Jul 31, 2018

Building off Diana's work in #97, makes the necessary changes to get flow passing so we can export types from our package (#94).

const Root = getOverride(RootOverride) || StyledRoot;
const Checkmark = getOverride(CheckmarkOverride) || StyledCheckmark;
const Label = getOverride(LabelOverride) || StyledLabel;
const Input = getOverride(InputOverride) || StyledInput;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed getComponent to getOverride, removing the defaultComponent arg.

The return type of getComponent was ?React.ComponentType<T>, meaning that it could return a component or null/undefined. So even if we know that null/undefined can't be returned because we've passed a valid default, flow will still complain that we can't use <Checkmark because it may be null/undefined.

For this reason, i think we should just switch to using a getOverride(override) || DefaultComponent pattern to avoid having to do null checks on the output before we use them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this change 👍 The return was nullable because it actually was allowed to accept null as a second arg and return null as a result (used in Before and After components in Input).

// TODO remove this 'any' once this flow issue is fixed:
// https://github.com/facebook/flow/issues/6666
// eslint-disable-next-line flowtype/no-weak-types
return (override: any).component;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vicapow said that this is probably the best solution for now

function getMockComponent<T>(): React.ComponentType<T> {
const mock: React.ComponentType<T> = () => null;
return mock;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think that we should be comfortable with using const mock: any = jest.fn();, as we do in many other tests, however I'm not using any jest mock functionality in this file so this stricter type works.

expect(toObjectOverride()).toBeUndefined();
// $FlowFixMe - Calling toObjectOverride with null
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be comfortable using $FlowFixMe in these cases. Not all customers will be using flow, so we may still want to test that our functions have certain behavior when passed bad input which doesn't match flow types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@schnerd why don't we be explicit with flow that the toObjectOverride can be called with no args or with null?
so toObjectOverride<T>(override?: ?OverrideT<T>): OverrideT<T>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it's not intended to be called with undefined/null, and if customers are using flow we should define types that protect against that. This is a test designed to make sure the function does sane things for customers who aren't using flow and pass bad data.

@schnerd schnerd mentioned this pull request Jul 31, 2018
const Root = getOverride(RootOverride) || StyledRoot;
const Checkmark = getOverride(CheckmarkOverride) || StyledCheckmark;
const Label = getOverride(LabelOverride) || StyledLabel;
const Input = getOverride(InputOverride) || StyledInput;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this change 👍 The return was nullable because it actually was allowed to accept null as a second arg and return null as a result (used in Before and After components in Input).

Copy link
Contributor

@DianaSuvorova DianaSuvorova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job @schnerd. Left one comment.

expect(toObjectOverride()).toBeUndefined();
// $FlowFixMe - Calling toObjectOverride with null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@schnerd why don't we be explicit with flow that the toObjectOverride can be called with no args or with null?
so toObjectOverride<T>(override?: ?OverrideT<T>): OverrideT<T>

@schnerd schnerd merged commit 5da54fd into master Jul 31, 2018
nadiia pushed a commit that referenced this pull request Aug 10, 2018
@abmai abmai deleted the ds-flow-fix branch August 13, 2018 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants