首页 > 解决方案 > graphql + mongoose + typescript,如何减少模型定义重复

问题描述

我使用mongoose,typescriptgraphql来构建我的应用程序。

我是一名全栈开发人员。

问题是我定义了模型的字段和类型五次

服务器端:

models/book.ts

// first time
interface IBook extends mongoose.Document {
  title: string;
  author: string;
} 

// second time
const bookSchema = new mongoose.Schema({
  title: String,
  author: String
})

const Book: mongoose.Model<IBook> = mongoose.model<IBook>('Book', bookSchema)

graphql/typeDefs.ts

const typeDefs = `
  // third time
  type Book {
    title: String!
    author: String!
  }

  // fourth time
  input BookInput {
    title: String!
    author: String!
  }
`

客户端:

interfaces/book.ts

// fifth time
interface IBook {
  title: string;
  author: string;
}

如你看到的。titleauthor字段和类型被定义了五次

主要有以下三个缺点:

  1. 重复
  2. 缺乏可维护性
  3. 效率低下

有没有办法解决这个问题?我认为这几乎是一个DRY问题。

以下是我的想法:

  1. 通用应用程序 - 提取客户端和服务器端使用的一些常用模块。
  2. 制作一个工具来处理这个。

    • 制作项目生成器或命令行工具,例如ng-cli用于静态生成模型和类型,这意味着在运行时之前

    • 在运行时进行模型定义decoratorsyntax sugar动态生成模型和类型

标签: graphqlgraphql-js

解决方案


我们最近遇到了这个问题,要求我们在 Mongoose 模式旁边维护一个重复的 Typescript 接口(对我们来说,问题只是服务器端,因为我们没有使用 graphql 或客户端 Typescript)

我们构建了 mongoose-tsgen来解决这个问题。它可能无法处理此处涉及的所有情况,但可以轻松引导以处理您的用例。

它读取您的 Mongoose 模式并生成一个index.d.ts文件,其中包含每个文档和子文档的接口。这些接口可以直接从 mongoose 模块导入,如下所示:

import { IUser } from "mongoose"

async function getUser(uid: string): IUser {
  // `user` is of type IUser
  const user = await User.findById(uid)
  return user;
}


推荐阅读