Skip to content

Instantly share code, notes, and snippets.

@lucascardial
Forked from NoriSte/redux-saga-typeguard.ts
Created June 29, 2020 17:44
Show Gist options
  • Save lucascardial/bca7fb22be447656a0d127dc75341ee2 to your computer and use it in GitHub Desktop.
Save lucascardial/bca7fb22be447656a0d127dc75341ee2 to your computer and use it in GitHub Desktop.
Redux-saga + Typescript: implementing typeguard for Axios AJAX requests
import { AxiosResponse } from "axios";
// the kind of data I expect from the AJAX request...
interface AuthData {
access_token?: string;
refresh_token?: string;
}
// ... a type dedicated to the Axios response...
type AuthResponse = AxiosResponse<AuthData>;
// ... and the function that consumes Axios... (it's a part of my own function but the rest of the
// body isn't helpful for the sake of the Gist)
function postRefresh(refreshToken: string): Promise<AuthResponse> {
return new Promise(async (resolve) => {
const response: AuthResponse = response = await Axios.post(/* ... */);
resolve(response);
});
}
// the saga that consumes the AJAX request
function* UNSAFE_refreshAuthSaga() {
// ...
// Typescript can't check the return type of yielded value. If 'postRefresh' returns a different
// type of response Typescript can't check it and compiles without errors
const response: AuthResponse = yield call(postRefresh, "the_refresh_token");
// ...
}
function* SAFE_refreshAuthSaga() {
// ...
// That's a strong typeguard check, useful to work around the Typescript impossibility of checking
// a yielded function return value
// tslint:disable-next-line
let typeguard: Equals<Promise<AuthResponse>, ReturnType<typeof postRefresh>>;
const response: PromiseArgType<typeof typeguard> = yield call(postRefresh, "the_refresh_token");
// now if I change the return type of the "postRefresh" function Typescript raises an error
// ...
}
// some more Typescript utilities
type Equals<A, B> = [A] extends [B] ? ([B] extends [A] ? A : never) : never;
// @see https://stackoverflow.com/questions/48011353/how-to-unwrap-type-of-a-promise?rq=1
type PromiseArgType<T> = T extends Promise<infer U>
? U
: T extends (...args: any[]) => Promise<infer UU>
? UU
: T;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment