facebook / facebook/flow

Intersection of two Generic Types: Is it possible?

Aperta
#4,899 0 commenti 2 reazioni 0 assegnatari Vedi su GitHub
question
Lingua principale
Rust
Stelle
22.3k
Fork
1.9k
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

Hi peeps, really appreciate the work you've put into flow! 🏅

I have tried my best to condense this problem.

# Background
I have been struggling with typing a generic HOC we use very commonly in our codebase.

```js
const adaptDataProp = dataAdapter => ComposedComponent =>
({ data, ...rest }) => ;
```

## What it does
- Apply an adapter function **only on the `data` prop**
- `data` is a prop populated with raw API data from our GraphQL server
- `adaptDataProp`accepts:
- a `dataAdapter` function which transforms `Data => AdaptedData`, e.g:
- `const dataAdapter = ({ foo }) => ({ bar: foo });`
- a React component with props, e.g.
```js
type Props = {
bar: string,
className: string
};

const View = ({ bar, className }: Props) => (

{bar}

);
```
- `adaptDataProp` should finally return:
- a React component which can be used as follows:
```js
const ViewWithData = adaptDataProp(dataAdapter)(View);
// render
;
```

# Problem/Question

1. Intersection between two generic types do not work as expected

```js
import React from 'react';
import type { ComponentType } from 'react';

function adaptDataProp(
dataAdapter: (Data) => AdaptedData
): (ComponentType => ComponentType<{ data: Data } & OtherProps>) {
return function (
ComposedComponent: ComponentType
): (ComponentType<{ data: Data } & OtherProps>) {
return function (
props: { data: Data } & OtherProps
) {
const { data, ...rest } = props;
const adaptedData = dataAdapter(data);
return ;
};
};
}

// Error
return ;
^ props of React element `ComposedComponent`. This type is incompatible with
8: ComposedComponent: ComponentType
^ some incompatible instantiation of `OtherProps`
```

## Assumption:
- Flow would be able to infer that `OtherProps` corresponds to all the props except `data` prop, i.e.
```js
{data, ...rest} = { data: Data } & OtherProps

Data -> type of data
OtherProps -> type of rest
```

[Link to Flow](https://flow.org/try/#0JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AoUSWOGATzCTgG84BhXSAOyS5gBUGTAL5xsuAkXQwy5cpgCuXDMAhc4KACYowMACIoYKAAo4wAHgNGANHACC23Uk1WUALhbDbAeRgALJChTCDAAZw9mYQA+AApyODhtIwcdGECPGNcASjgAXij7RzSXQxRyLIyOcDVeASFzFKcSozgAMjhfAKCzUIL89k4avkFGc1Yk9zhXOFF2zsDgsKic5ni4IhgFKHVFZRhVdTiEhKrIUOdToZgPS55h+sbi6bn-BZ6otYq4GNvakaQxolSh5prMOq9uiFeis1gkNlsdkoVGpvrDjmAehEgUYQaUZm1wV1FqE0TDjsc0GpQvBxqVbAA6RlEan43JwDFQijkhKUrgsrSpZzTNkTR6BGITLJc7nw7ZwcyXc6aX58FiM+nMmCiZjqgVNVyiAD0UWlCWE0vN5GEcht5CAA)

# What I have attempted
- Switching the order of the intersections, e.g. `A & B` -> `B & A`
- Tried to spread `{...Other}` instead of using Intersections

I suspect it might be related to Object spread or intersection issues. However, my understanding of using generic types and how they work might be wrong. I have tried unsuccessfully to type that HOC for many weeks now.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.