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

Expected functionality of $Diff #3396

Open
echenley opened this issue Feb 16, 2017 · 0 comments
Open

Expected functionality of $Diff #3396

echenley opened this issue Feb 16, 2017 · 0 comments
Labels

Comments

@echenley
Copy link

echenley commented Feb 16, 2017

I know there are other issues related to $Diff, but I wanted to lay out a particular use case that would eliminate a lot of the pain of using flow to type higher order functions and React components.

Current Scenario

Currently, flow forces you to manually diff objects, exemplified by the Translator HOC in the libdef for react-i18next:

declare type Translator<OP, P> = {
  (component: StatelessComponent<P>): Class<React$Component<void, OP, void>>;
  <Def, St>(component: Class<React$Component<Def, P, St>>): Class<React$Component<Def, OP, St>>;
}

(this was in modeled after react-redux's Connector, which could probably also benefit from $Diff)

And it's usage:

type Props = { a: string }
type PropsWithT = Props & { t: TFunction }

const MyComponent = (props: PropsWithT) => /* something */

const translator: Translator<Props, PropsWithT> = translate('something')
const WrappedComp = translator(MyComponent)

// doesn't complain about missing props.t
<WrappedComp a="string" />

Notice how you have to pass in props for the HOC and for the original component?

Ideal Scenario

Ideally, you could use $Diff to do that work for you:

declare type Translator<P> = {
  (component: StatelessComponent<P>): Class<React$Component<void, $Diff<P, { t: TFunction }>, void>>;
  <Def, St>(component: Class<React$Component<Def, P, St>>): Class<React$Component<Def, $Diff<P, { t: TFunction }>, St>>;
}

Usage then becomes:

type Props = { a: string, t: TFunction }

const MyComponent = (props: Props) => /* something */

const translator: Translator<Props> = translate('something')
const WrappedComp = translator(MyComponent)

// doesn't complain about missing props.t
<WrappedComp a="string" />

Non-React HOF

An example of where $Diff could be used to type generic higher order functions:

type Obj = {
  a: string,
  b: string
}

const fn = (obj: Obj) => obj.a + obj.b

const hof = <Obj>(
  fn: (obj: Obj) => string
): (obj: $Diff<Obj, { b: string }>) => string => {
  return (obj) => fn({ ...obj, b: 'b' })
}

const fn2 = hof(fn)

// doesn't complain about missing obj.b
fn2({ a: 'a' })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants