Intersection of two Generic Types: Is it possible?
- Dominant language
- Rust
- Stars
- 22.3k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
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) => (
);
```
- `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.
Contributor guide
Assessment
This issue has not been assessed yet.