typed-graphqlify 最佳实践:大型项目 TypeScript 类型化 GraphQL 查询的 8 个工程化技巧
【免费下载链接】typed-graphqlifyBuild Typed GraphQL Queries in TypeScript without the code generation项目地址: https://gitcode.com/gh_mirrors/ty/typed-graphqlify
typed-graphqlify 是一个无需代码生成、直接在 TypeScript 中构建类型化 GraphQL 查询的开源库。它用一套「类 GraphQL」的 JavaScript 对象,同时产出查询字符串与精确的 TypeScript 类型,让查询定义成为唯一事实来源。这份 typed-graphqlify 最佳实践清单,专为新手和普通用户整理,汇总了 8 个大型项目中真正用得上的工程化技巧,帮助你快速上手、少踩坑。
上图是 typed-graphqlify 最迷人的时刻:当你在代码里输入result.user.时,编辑器自动弹出id、name、bankAccount的精确类型,而这一切不需要任何代码生成步骤。
30 秒理解核心思想:为什么说它是「TypeScript + GraphQL 的更好体验」
传统 Apollo 开发中,我们要同时维护两份代码:一份 GraphQL 查询字符串,一份手写的 TypeScript 接口。加一个字段就要改两处,漏改一处编译器也不会报错,类型不同步的问题几乎每天都会遇到。
typed-graphqlify 的做法是:只写一遍定义。
import { query, types } from 'typed-graphqlify' const getUserQuery = query('GetUser', { user: { id: types.number, name: types.string, bankAccount: { id: types.number, branch: types.optional.string, }, }, })getUserQuery.toString()生成 GraphQL 字符串,typeof getUserQuery.data得到完整 TypeScript 类型。一次定义,双份收获。
安装方式
npm install --save typed-graphqlify # 或 yarn add typed-graphqlify下面进入正题,8 个工程化技巧一次讲清 👇
技巧 1:用单一数据源消除查询与类型「失同步」
这是 typed-graphqlify 存在的根本理由。查询字段和返回类型由同一份对象定义,增删字段永远只改一处,改完类型立即跟着变,编译器帮你兜底。
在大型项目中,推荐把所有查询定义集中在queries/目录,每个实体一个文件(例如user.ts、order.ts),团队其他人复用时就绝不会出现「接口定义和实际返回不一致」的尴尬。
技巧 2:善用 types 辅助器,声明字段类型不再痛苦
types是库内置的标量类型辅助器,核心 API 一览:
| 写法 | 推断出的 TypeScript 类型 |
|---|---|
types.number | number |
types.string | string |
types.boolean | boolean |
types.optional.string | string \| undefined |
types.constant('User') | 固定值'User'(如__typename) |
types.oneOf([...]) | 枚举联合类型 |
types.custom<T>() | 任意自定义类型 |
实现位于src/types.ts,逻辑非常直白,遇到看不懂的写法直接翻源码即可。
技巧 3:用 alias 处理别名与字段参数,查询更灵活
需要给字段换名字、或者给字段传参时,用alias和params这两个辅助函数:
import { alias, query, types, params, rawString } from 'typed-graphqlify' query('getMaleUser', { [alias('maleUser', 'user')]: { id: types.number, createdAt: params({ format: rawString('d.m.Y') }, types.string), }, })alias('maleUser', 'user')输出maleUser: user,返回数据的键名与 GraphQL 别名一致;params(参数对象, 字段类型)用于内联参数;rawString确保字符串参数被正确渲染成字符串字面量而非枚举。
技巧 4:用 fragment 复用公共字段,告别复制粘贴
大型项目中「用户基础信息」这类字段会在十几个查询里重复出现,这时候就该用fragment:
import { fragment, query, types } from 'typed-graphqlify' const userFragment = fragment('userFragment', 'User', { id: types.number, name: types.string, }) query('getUsers', { users: [{ ...userFragment, // 展开复用 role: types.oneOf(['ADMIN', 'MEMBER']), }], })Fragment 支持嵌套,公共字段改动时只需维护一处,查询字符串会自动拼出完整的fragment ... on ...声明,详见src/graphqlify.ts中的fragment实现。
技巧 5:用 on / onUnion 优雅处理联合类型
GraphQL 的联合类型(Union)在传统写法里需要手动写判别逻辑,typed-graphqlify 的onUnion会自动生成联合类型A | B:
import { onUnion, query, types } from 'typed-graphqlify' query('getHero', { hero: { id: types.number, ...onUnion({ Droid: { kind: types.constant('Droid'), primaryFunction: types.string }, Human: { kind: types.constant('Human'), height: types.number }, }), }, })拿到结果后,用if (hero.kind === 'Droid')即可安全地类型收窄,配合判别联合模式,分支逻辑再也不怕写错字段。
技巧 6:用 types.oneOf 定义枚举,消灭魔法字符串
枚举用数组或普通对象定义即可,推荐数组配合as const:
const userType = ['STUDENT', 'TEACHER'] as const query('getUser', { user: { id: types.number, type: types.oneOf(userType), // 推断为 'STUDENT' | 'TEACHER' }, })注意:官方建议避免使用 TypeScript 原生enum来定义(类型推断无法保证完全正确),数组或普通对象是最稳的选择。
技巧 7:与请求层解耦,无缝对接 Apollo 等客户端
typed-graphqlify 只负责「生成字符串 + 推导类型」,请求交给任意客户端执行:
const data: typeof getUserQuery.data = await executeGraphql(getUserQuery.toString())它与 Apollo、graphql-request 甚至自己封装的 fetch 都能配合。相比apollo client:codegen,它的优势在于:逻辑简单、不依赖 schema 也能工作、天然支持多 schema 场景,还能在像「AWS 管理控制台」这种动态构建查询的界面里程序化地拼查询而不丢失类型信息。
技巧 8:工程化收尾——构建、测试与 React Native 注意事项
- 构建产物:项目用 Rollup 产出 ES Module 与 CommonJS 双格式(
rollup.config.js),保证库在各种构建工具下都能正常工作; - 测试:
jest+ts-jest覆盖核心渲染逻辑,参考src/__tests__/下的测试用例,遇到边界行为直接看测试是最快的理解方式; - 代码规范:
prettier负责格式化、tslint负责静态检查,接入 lint-staged 在提交前自动校验; - React Native 注意:库内部使用
Symbol与Map,若目标环境是 ES5,需要在入口引入babel-polyfill补齐 polyfill,否则会运行时报错。
总结
typed-graphqlify 的核心理念用一个词概括就是「单一数据源」:查询字符串与 TypeScript 类型由同一份定义生成,从根上解决了 GraphQL 客户端最常见的类型失同步问题。本文的 8 个技巧——从types辅助器、alias/params,到fragment复用、onUnion联合类型,再到请求层解耦与构建测试——覆盖了大型项目中最常用的场景。
上手成本很低:先看examples/index.ts里的完整示例,再对照src/__tests__/index.test.ts的测试用例验证各种写法,很快你就能把这套「免代码生成」的类型化 GraphQL 开发体验带进自己的项目里。
【免费下载链接】typed-graphqlifyBuild Typed GraphQL Queries in TypeScript without the code generation项目地址: https://gitcode.com/gh_mirrors/ty/typed-graphqlify
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考