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

$Diff with ...rest doesn't work #3541

Closed
sepo-one opened this issue Mar 19, 2017 · 9 comments
Closed

$Diff with ...rest doesn't work #3541

sepo-one opened this issue Mar 19, 2017 · 9 comments

Comments

@sepo-one
Copy link

Example:

/* @flow */

type Props = {
	title: string;
  	age: number;
};

type WrapProps = $Diff<Props, {
	age: number;
}>;

const Person = (props: Props) => {};
const YoungPerson = (props: WrapProps) => {
	return Person({age: 21, ...props});
};

Gives an error:

14: 	return Person({age: 21, ...props});
                   ^ object literal. Expected object instead of
14: 	return Person({age: 21, ...props});
                                ^ Props

However if i declare WrapProps sub type manually, it works:

/* @flow */

type Props = {
	title: string;
  	age: number;
};

/*type WrapProps = $Diff<Props, {
	age: number;
}>;
*/

type WrapProps = {
	title: string;
};

const Person = (props: Props) => {};
const YoungPerson = (props: WrapProps) => {
	return Person({age: 21, ...props});
};

Seems like $Diff is not working correctly.

@niieani
Copy link

niieani commented Mar 26, 2017

Indeed, you can't use the spread type on a $Diff type either:

type SpreadFromDiff = {...$Diff<Props, {title: string}>}

@vkurchatkin
Copy link
Contributor

$Diff is not a public feature. It only works properly as lower bound, i.e. you can assign something to it, but can't use it after that

@sepo-one
Copy link
Author

sepo-one commented Mar 27, 2017

but the first example should work, right ?
i mean when using rest on the actual value that has been typed with $Diff

@vkurchatkin
Copy link
Contributor

No, it shouldn't. $Diff only works properly as argument in declarations

@jacobk
Copy link

jacobk commented Apr 7, 2017

@vkurchatkin it's publicly documented https://flow.org/en/docs/types/utilities/#toc-diff and I don't see how that example is different from the example in this issues (sans the ... spread).

It would be great if you can provide an example of how it can be used since I've tried $Diff multiple times without success and I'm afraid I don't follow any of the explanations above :(

@jacobk
Copy link

jacobk commented Apr 7, 2017

$Diff aside, is there any other idiomatic way to annotate react components that wrap another component and exposing a subset of the wrapped component's props (i.e. providing the rest itself inside the wrapper)?

Edit
(Without declaring all the re-exposed props, which might be many and complex)

@vkurchatkin
Copy link
Contributor

Here is as simple example:

type X = $Diff<{ a: string}, {}>;
var x: X = { a: 'string' }; // This works as expected
x.a; // This is an error

Each type consists of two parts: upper bound and lower bound. Upper bound defines if you can assign something to the type (i.e. if it's a subtype of the type). Lower bound defines if you can use the type in some particular way. $Diff only implements upper bound, so once you have something of type $Diff you can't do anything with it.

So if you want to use $Diff in your code you have to cast it to any. This is probably fine if you take $Diff as an argument, but not ideal if you return it from a function.

@jacobk
Copy link

jacobk commented Apr 7, 2017

@vkurchatkin thanks for the example, that clears things up, really helpful!

Just a detail, in the other post above you wrote "lower bound" and this reply "upper bound" (which matches your explanation for $Diff)

@Andarist
Copy link

Issue described by @vkurchatkin above doesn't seem to be an issue any longer since flow 0.57

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants