Búsqueda de sitios web

Typescript - convertir el tipo de ObjectId de mongoose a cadena al compartir entre backend y frontend


Estoy intentando crear algunos tipos basados en modelos de esquema de mongo y compartirlos con el front-end en un mono repositorio.

Tipo de ejemplo:

import { Types } from "mongoose";

export interface Profile {
  userId: Types.ObjectId;
  education: {
    university: Types.ObjectId;
  };
}

Mi esquema de perfil usa esta interfaz de Perfil para definir tipos y la misma interfaz se usa en el front-end. Dado que el front-end no necesita conocer los tipos de mongoose, me gustaría tener userId y education.university como cadena. Por cierto, cuando obtengo la respuesta de la API desde el servidor en el front-end, recibo estos valores solo como cadenas.

He probado un mapeador de TS tal como se define maravillosamente aquí. Esto resolvió mi problema parcialmente: puedo ver que userId se convierte en cadena en el front-end. Pero esto no resuelve el objeto anidado education. Puedo definir education como un tipo separado y usar el mapeador, pero creo que esta no es una forma escalable. Me gustaría que el mapeador manejara la conversión de tipos de los tipos anidados también.

typeMapper.ts
import { Types } from "mongoose";

type MapObjectIdToString<PropType> = PropType extends Types.ObjectId
  ? string
  : PropType;

  export type MapDbObject<T> = {
    [PropertyKey in keyof T]: MapObjectIdToString<T[PropertyKey]>;
  };

Estoy convirtiendo el tipo Profile de esta manera

export type UiProfile = MapDbObject<Profile>; // here `userId` is string, but `university` is still Types.ObjectId

¿Hay alguna manera de actualizar mi TS Mapper para convertir todos los campos, incluidos los campos dentro de objetos anidados, de Types.ObjectId a string? Gracias de antemano.

Respuesta #1

Un tipo recursivo lo hará:

type StringIds<T> = T extends Types.ObjectId ? string : T extends Record<any, any> ? {
    [K in keyof T]: StringIds<T[K]>;
} : T;

También funciona con arrays. Pruébalo tú mismo a continuación:

Parque infantil