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

Any plan on effect return types? #9

Open
git9am opened this issue Oct 18, 2020 · 1 comment
Open

Any plan on effect return types? #9

git9am opened this issue Oct 18, 2020 · 1 comment

Comments

@git9am
Copy link

git9am commented Oct 18, 2020

This project offers a way to ensure typing between Components and Models. But we still have typing issues within Models since yield ends up with an any return type, as is explained under microsoft/TypeScript#2983. E.g. in redux-saga Models we often have cases like:

const result = yield this.effects.call(fn, payload);  // <- result is any

Models plays an important role in firing API calls and gathering API responses. And since that's error-prone for data typing, it would be very helpful to make those effect calls type sensitive.

For example, we may wrap effects.call into another generator with type declaration, so that we have:

In lib/BaseModel.d.ts,

type FunctionType = (() => any) | ((...args: any) => any);
type Unpromise<T extends FunctionType> = ReturnType<T> extends Promise<infer U> ? U : ReturnType<T>; // TODO: T may extend Generator
export interface EffectsCommandMap<StoreState> extends DvaEffectsCommandMap {
    // ...
    call<F extends FunctionType>(func: F, ...args: any): Generator<Unpromise<F>, Unpromise<F>>,
    // ...
}

In src/decorators/effect.ts,

const _call = effects.call;
currentThis.effects.call = function*(func: any, ...args: any) {
    return (yield _call(func, ...args));
};

And in model files, by replacing yield with yield*,

const result = yield* this.effects.call(fn, payload);  // <- result is now the return type of fn

Will such a patch make sense to this project?

@yehq
Copy link
Owner

yehq commented Nov 12, 2020

Thanks for your suggestion!
You have to give it a new name like yieldCall.
eg.

const _call = effects.call;
currentThis.effects.yieldCall = function*(func: any, ...args: any) {
    return (yield _call(func, ...args));
};

Maybe you can give me a PR!

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

No branches or pull requests

2 participants