-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Use return type of a function #4002
Comments
There are a couple of hacky ways to do this:
type Return_<R, Fn: () => R> = R;
type Return<T> = Return_<*, T>;
function foo() {
return 1;
}
const x: Return<typeof foo> = ''; // error
function foo() {
return 1;
}
/*::
const __result = foo();
*/
const x: typeof __result = ''; |
@vkurchatkin Awesome example, I am now wondering why does the same trick not work for the function arguments: type Return_<R, F: (...args: Array<any>) => R> = R;
type Return<T> = Return_<*, T>;
type Arguments_<A, F: (...args: A) => any> = A;
type Arguments<F> = Arguments_<*, F>;
function foo(n: number) {
return n;
}
const r: Return<typeof foo> = ''; // error
const a: Arguments<typeof foo> = ['']; // no error :( |
That's because type of arguments flows in the opposite direction. var x: * = 1; // number ~> *
declare var y: typeof x;
(y: string); // error
declare function fn(x: number): void;
declare var z: *;
fn(z); // * ~> number
declare var u: typeof z;
(u: string); // no error The same happens when function flows into another function, like in your example. |
@vkurchatkin Do you think your |
Not |
@nickmessing is this working for u? Do u have a repo example of this? |
@sibelius, yes, this helper works fine: type Return_<R, F: (...args: Array<any>) => R> = R;
type Return<T> = Return_<*, T>; |
Add ExtractReturn helper// https://hackernoon.com/redux-flow-type-getting-the-maximum-benefit-from-the-fewest-key-strokes-5c006c54ec87
// https://github.com/facebook/flow/issues/4002
// eslint-disable-next-line no-unused-vars
type _ExtractReturn<B, F: (...args: any[]) => B> = B;
export type ExtractReturn<F> = _ExtractReturn<*, F>; Extract return of mapStateToProps and mapDispatchToPropsconst mapStateToProps = state => ({
user: state.user,
});
const mapDispatchToProps = dispatch => ({
actions: {
logout: () => dispatch(logout()),
},
});
type ReduxProps = ExtractReturn<typeof mapStateToProps>;
type ReduxActions = ExtractReturn<typeof mapDispatchToProps>; Add ReduxProps and ReduxActions to your Component propstype Props = {} & ReduxProps & ReduxState
class EntriaComp extends Component<Props> {} I think we can use cc @calebmer can we close this? |
Can ExtractReturn be added to the global Flow helpers as $Return? |
you can use $Call instead of ExtractReturn |
Proposed solutions do not work for my case: Flow Try I need to explicitly type returns of The dream is using const actionCreators = {
// ...
};
export type Action = $Values<$ObjMap<typeof actionCreators, ExtractReturnType>>; Edit: I think my problem is that the inferred return types not being literal. I guess what I need from Flow is return type of a function like |
Hi everyone, @vkurchatkin, so based on what you wrote on this comment, I assume there is no way to extract function arguments, or is any? |
I can't get it to work either. Here's a very simple example. Does not throw: type Props = ReduxProps & { user: string };
this.props.user.foo(); Does throw: type Props = { user: string };
this.props.user.foo(); When using UPDATE Finally got it to work using spread and exact helper! type Props = {|
...ReduxProps,
customProp: customType
|} |
This probably can be closed. |
Hi @kangax, I've just seen your comment, would you mind to share I'm asking you this as I believe the error you were having was caused by the fact that when intersecting types (using &) if any of the them share a property, the resulting type would hold on that property an union of all the values for it, does it make sense? was your error caused by this? |
this is the version using export type ExtractReturn<Fn> = $Call<<T>((...Iterable<any>) => T) => T, Fn>; Example of extracting ReduxProps: type ReduxProps = ExtractReturn<typeof mapStateToProps>; |
can we close this? |
Sure 👍 |
I'm having some issues with typing const mapActionsToProps = {
logout
}
connect(null, mapActionsToProps)(Comp) Since it's a simple object of functions, I should be able to use type ReduxActions = typeof mapActionsToProps
type Props = {} & ReduxActions // or type Props = { ...ReduxActions }
class Comp extends Component<Props> {} But it doesn't work, Flow loses the inferred type of the actions and see them as I reported the bug (?) here: #6797 Does someone have a workaround? Or am I doing something wrong? (cc @sibelius ) Edit: so it appears only when the actions are imported from another file. 🤯 |
Hello. I am trying to extract union type of "foo":
|
Hello, can't figure out how to use function asd(): Promise<number> {
return Promise.resolve(3);
}
(async () => {
const num: $Call<typeof asd> = await asd();
})() Getting error:
Promise chain also not working as expected: function asd(): Promise<number> {
return Promise.resolve(3);
}
asd().then((num: $Call<typeof asd>) => {}); Getting error:
|
function asd(): Promise<number> {
return Promise.resolve(3);
}
(async () => {
const num: $Call<typeof $await, $Call<typeof asd>> = await asd();
})() |
Flow finds return type of functions very well, can we use that type in other declarations in any way?
Example of what I would like to achieve:
The text was updated successfully, but these errors were encountered: