If I $Diff an object that contains maybe properties with one that has the same properties but without the maybe, we receive an odd type error:
type SomeProps = {
id: number,
name?: string,
};
type SomePropsWithoutName = $Diff<SomeProps, {name: string}>;
const foo: SomePropsWithoutName = {id: 1}
6: type SomePropsWithoutName = $Diff<SomeProps, {name: string}>;
^ Cannot instantiate `$Diff` because undefined [1] is incompatible with string [2].
References:
3: name?: string,
^ [1]
6: type SomePropsWithoutName = $Diff<SomeProps, {name: string}>;
This is useful to do with e.g. React-Redux's connect() functionality, where you might inject props into a component and return one with a new type signature where the properties you provided are no longer required. If one of the properties you provide fills in a maybe type (name? above), the resulting Props are not correct.
I've managed to work around it with $ObjMap:
type SomeProps = {
id: number,
name?: string,
another: string
};
type MakeMaybeMember = <V>(V) => ?V;
type MergeType = {name: string, another: string};
type SomePropsWithoutName = $Diff<SomeProps, $ObjMap<MergeType, MakeMaybeMember>>;
const foo: SomePropsWithoutName = {id: 1}
I've worked around this by diffing with an object with optional properties:
type SomeProps = {
id: number,
name: string,
};
type SomePropsWithoutName = $Diff<SomeProps, {name?: string}>;
const foo: SomePropsWithoutName = {id: 1}
Yeah. Issue is that I don't always control the type that's behind diffed.
It is often inferred from a function and thus is not an optional type.
Is there a reason why $Diff cares about the values of the object type properties at all? To me $Diff should only care about the keys and completely ignore the property values.
I did encounter scenarios where the value type mattered. As a workaround you can use any as a value, which seemed to work for me in all situations.
type WithoutBar = $Diff<Foo, {bar?: any}>;
I did encounter scenarios where the value type mattered.
Like what?
Seems like a $DiffAsYouWouldExpectItToWork type is needed:
type $DiffAsYouWouldExpectItToWork<Props, PropsToRemove> = $Diff<SomeProps, $ObjMap<PropsToRemove, <V>(V) => any>>;
type SomeProps = {
id: number,
name?: string,
};
type SomePropsWithoutName = $DiffAsYouWouldExpectItToWork<SomeProps, {name: string}>;
const foo: SomePropsWithoutName = {id: 1}
This is preventing my team from taking full advantage of Flow when using react-redux. My team is willing to invest some time fixing this, but some details would go a long way.
Here are my questions.
Let me know, thanks!
Most helpful comment
This is preventing my team from taking full advantage of Flow when using react-redux. My team is willing to invest some time fixing this, but some details would go a long way.
Here are my questions.
Let me know, thanks!