Skip to content

Commit 93aa7d6

Browse files
Enhance type safety in Auth0Provider and reducer by introducing generic user type (#842)
### 🔄 Changes - Enhanced type safety in `Auth0Provider` and its reducer by introducing a generic user type. - Updated `Auth0ProviderOptions` interface to accept a generic user type. - Modified the `onRedirectCallback` function to accept the generic user type. - Updated the reducer function to handle the generic user type. ### 🧪 Testing - The changes were tested by integrating them to a sample app and verifying with a generic user type ### 💥 Impact - Improved type safety for the `Auth0Provider` component and reducer. - No changes to the functionality of the component are expected. - No performance impact is anticipated. - This PR addresses issue mentioned in #748 ### 📋 Checklist - [x] Code follows the project's coding standards - [x] All tests are passing
1 parent 44477f8 commit 93aa7d6

File tree

2 files changed

+11
-11
lines changed

2 files changed

+11
-11
lines changed

src/auth0-provider.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
deprecateRedirectUri,
2929
} from './utils';
3030
import { reducer } from './reducer';
31-
import { initialAuthState } from './auth-state';
31+
import { initialAuthState, type AuthState } from './auth-state';
3232

3333
/**
3434
* The state of the application before the user was redirected to the login page.
@@ -41,7 +41,7 @@ export type AppState = {
4141
/**
4242
* The main configuration to instantiate the `Auth0Provider`.
4343
*/
44-
export interface Auth0ProviderOptions extends Auth0ClientOptions {
44+
export interface Auth0ProviderOptions<TUser extends User = User> extends Auth0ClientOptions {
4545
/**
4646
* The child nodes your Provider has wrapped
4747
*/
@@ -51,7 +51,7 @@ export interface Auth0ProviderOptions extends Auth0ClientOptions {
5151
* It uses `window.history` but you might want to overwrite this if you are using a custom router, like `react-router-dom`
5252
* See the EXAMPLES.md for more info.
5353
*/
54-
onRedirectCallback?: (appState?: AppState, user?: User) => void;
54+
onRedirectCallback?: (appState?: AppState, user?: TUser) => void;
5555
/**
5656
* By default, if the page url has code/state params, the SDK will treat them as Auth0's and attempt to exchange the
5757
* code for a token. In some cases the code might be for something else (another OAuth SDK perhaps). In these
@@ -83,7 +83,7 @@ export interface Auth0ProviderOptions extends Auth0ClientOptions {
8383
*
8484
* For a sample on using multiple Auth0Providers review the [React Account Linking Sample](https://github.com/auth0-samples/auth0-link-accounts-sample/tree/react-variant)
8585
*/
86-
context?: React.Context<Auth0ContextInterface>;
86+
context?: React.Context<Auth0ContextInterface<TUser>>;
8787
}
8888

8989
/**
@@ -132,7 +132,7 @@ const defaultOnRedirectCallback = (appState?: AppState): void => {
132132
*
133133
* Provides the Auth0Context to its child components.
134134
*/
135-
const Auth0Provider = (opts: Auth0ProviderOptions) => {
135+
const Auth0Provider = <TUser extends User = User>(opts: Auth0ProviderOptions<TUser>) => {
136136
const {
137137
children,
138138
skipRedirectCallback,
@@ -143,7 +143,7 @@ const Auth0Provider = (opts: Auth0ProviderOptions) => {
143143
const [client] = useState(
144144
() => new Auth0Client(toAuth0ClientOptions(clientOpts))
145145
);
146-
const [state, dispatch] = useReducer(reducer, initialAuthState);
146+
const [state, dispatch] = useReducer(reducer<TUser>, initialAuthState as AuthState<TUser>);
147147
const didInitialise = useRef(false);
148148

149149
const handleError = useCallback((error: Error) => {
@@ -158,7 +158,7 @@ const Auth0Provider = (opts: Auth0ProviderOptions) => {
158158
didInitialise.current = true;
159159
(async (): Promise<void> => {
160160
try {
161-
let user: User | undefined;
161+
let user: TUser | undefined;
162162
if (hasAuthParams() && !skipRedirectCallback) {
163163
const { appState } = await client.handleRedirectCallback();
164164
user = await client.getUser();
@@ -272,7 +272,7 @@ const Auth0Provider = (opts: Auth0ProviderOptions) => {
272272
[client]
273273
);
274274

275-
const contextValue = useMemo<Auth0ContextInterface<User>>(() => {
275+
const contextValue = useMemo<Auth0ContextInterface<TUser>>(() => {
276276
return {
277277
...state,
278278
getAccessTokenSilently,

src/reducer.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type Action =
1717
/**
1818
* Handles how that state changes in the `useAuth0` hook.
1919
*/
20-
export const reducer = (state: AuthState, action: Action): AuthState => {
20+
export const reducer = <TUser extends User = User>(state: AuthState<TUser>, action: Action): AuthState<TUser> => {
2121
switch (action.type) {
2222
case 'LOGIN_POPUP_STARTED':
2323
return {
@@ -29,7 +29,7 @@ export const reducer = (state: AuthState, action: Action): AuthState => {
2929
return {
3030
...state,
3131
isAuthenticated: !!action.user,
32-
user: action.user,
32+
user: action.user as TUser | undefined,
3333
isLoading: false,
3434
error: undefined,
3535
};
@@ -41,7 +41,7 @@ export const reducer = (state: AuthState, action: Action): AuthState => {
4141
return {
4242
...state,
4343
isAuthenticated: !!action.user,
44-
user: action.user,
44+
user: action.user as TUser | undefined,
4545
};
4646
case 'LOGOUT':
4747
return {

0 commit comments

Comments
 (0)