Saltar al contenido

Generar tipos TypeScript para GraphQL y MongoDB — Numio

Genera tipos TypeScript de documentos MongoDB a partir de un esquema anotado con @entity, @id, @column, @link, @embedded y @map, usando @graphql-codegen/typescript-mongodb. Cada tipo con @entity recibe un tipo <Name>DbObject; los campos sin directiva se omiten.

Mantener tipada la forma del documento almacenado en MongoDB junto a los tipos de la API GraphQL de la misma entidad.

GraphQL Schema

TypeScript MongoDB

Cuándo usarla

  • Mantener tipada la forma del documento almacenado en MongoDB junto a los tipos de la API GraphQL de la misma entidad.
  • Ver cómo se traducen las rutas de @map y las referencias de @link a objetos anidados y arrays de ObjectId antes de escribir el código de acceso a datos.

Cómo usarla

  1. Pega un esquema cuyos tipos usen @entity y cuyos campos usen @id, @column, @link, @embedded o @map(path: ...).
  2. Revisa los tipos DbObject hacia el final de la salida; los tipos GraphQL en sí se generan encima de ellos.
  3. Copia el resultado en un archivo .ts; importa ObjectId del paquete mongodb.

Esquema GraphQL con directivas de MongoDB

type User @entity {
  id: ID! @id
  email: String! @column @map(path: "login.email")
  profile: Profile! @embedded
  posts: [Post!]! @link
}

type Profile @entity(embedded: true) {
  name: String! @column
}

type Post @entity {
  id: ID! @id
  title: String! @column
}

Tipos DbObject de TypeScript

…
export type AdditionalEntityFields = {
  path?: InputMaybe<Scalars["String"]["input"]>
  type?: InputMaybe<Scalars["String"]["input"]>
}

import { ObjectId } from "mongodb"
export type UserDbObject = {
  _id: ObjectId
  login: {
    email: string
  }
  profile: ProfileDbObject
  posts: Array<PostDbObject["_id"]>
}

export type ProfileDbObject = {
  name: string
}

export type PostDbObject = {
  _id: ObjectId
  title: string
}

Detalles y limitaciones

@id pasa a _id: ObjectId, @link pasa al _id de la entidad enlazada (Array<PostDbObject["_id"]> para listas) y @map(path: "login.email") crea un objeto login anidado.

Los campos sin directiva (sin @column, @id, @link ni @embedded) no se incluyen en el tipo DbObject; las columnas nullable pasan a propiedades Maybe<T> opcionales.

La salida también contiene los tipos estándar del plugin typescript (omitidos arriba). La generación se ejecuta en un Web Worker de tu navegador.

FAQ

¿Tengo que declarar las directivas @entity y @column en mi esquema?

No. El plugin añade sus propias definiciones de directivas, y por eso también aparece un tipo input AdditionalEntityFields en la salida.

¿Cómo se tipan los documentos embebidos?

Un tipo declarado con @entity(embedded: true) recibe un tipo DbObject sin _id, y un campo marcado con @embedded hace referencia a él, por ejemplo profile: ProfileDbObject.

¿Por qué falta un campo en el tipo DbObject?

Solo los campos con @id, @column, @link, @embedded o @map son campos almacenados. Añade @column para incluir un campo simple.

Especificaciones y referencias