Mieux typer les Metadata des utilisateurs Clerk avec NextJS et TypeScript
UserPublicMetadata / UserPrivateMetadata / UserUnsafeMetadata
Publié le 17 mai 2024 par Pierre Guézennec
Lors de l'utilisation de Clerk au sein d'une application Typescript, par exemple via sa librairie NextJs @clerk/nextjs
, on aura tendance à vouloir typer plus finement les métadonnées associées aux utilisateurs. Ces Metadata sont réparties en trois catégories :
- Private Metadata : accessibles en lecture et écriture seulement côté serveur ;
- Public Metadata : accessibles en lecture côté client et en lecture et écriture côté serveur ;
- Unsafe Metadata : accessibles en lecture et écriture côté client et serveur.
Rendez-vous sur le site de Clerk pour une documentation plus complète.
Pour récupérer les métadonnées associées à un utilisateur, par exemple pour les Public Metadata sur un composant côté client de Next.js, on utilise généralement l'objet user
du hook useUser()
:
1import { useUser } from "@clerk/nextjs";
1const { user } = useUser();
2const publicMetadata = user?.publicMetadata;
Le type associé sera le suivant :
1{
2 [k: string]: unknown;
3}
Il est défini au sein du fichier node_modules/@clerk/types/dist/user.d.ts
de la librairie de Clerk :
1declare global {
2 /**
3 * If you want to provide custom types for the user.publicMetadata object,
4 * simply redeclare this rule in the global namespace.
5 * Every user object will use the provided type.
6 */
7 interface UserPublicMetadata {
8 [k: string]: unknown;
9 }
10 /**
11 * If you want to provide custom types for the user.privateMetadata object,
12 * simply redeclare this rule in the global namespace.
13 * Every user object will use the provided type.
14 */
15 interface UserPrivateMetadata {
16 [k: string]: unknown;
17 }
18 /**
19 * If you want to provide custom types for the user.unsafeMetadata object,
20 * simply redeclare this rule in the global namespace.
21 * Every user object will use the provided type.
22 */
23 interface UserUnsafeMetadata {
24 [k: string]: unknown;
25 }
26}
Comme l'indique le commentaire, Clerk nous laisser affiner son typage par défaut en redéclarant la règle souhaitée au sein du namespace global.
Pour cela, au sein de Next.js, il suffit de créer le fichier suivant :
src/custom.d.ts
Avec ce contenu, par exemple, à ajuster selon les spécifications de votre projet :
1declare global {
2 interface UserPublicMetadata {
3 displayName?: string;
4 birthdate?: Date;
5 }
6}
7
8export default global;
9
Et c'est tout !
Vous pourrez constater au sein de VSCode que l'autocomplétion est fonctionnelle :