Last active
November 1, 2023 02:22
-
-
Save NoriSte/936096262be7af6b6bd4cba7a71640d9 to your computer and use it in GitHub Desktop.
Redux-saga + Typescript: implementing typeguard for Axios AJAX requests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Hey, i created a post with this solution, follow the link if you are interested.
Thanks! Just a suggestion: in dev.to, instead of adding code comments through a triple backtick
```
const a = 1
```
suffix the opening backticks with the language (js
or ts
in your case)
```ts
const a = 1
```
to leverage code highlight 😉
The result is something like
const a = 1
instead of
const a = 1
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, I didn't know
SagaReturnType
! ❤️