TypeScript中如何提取自动生成GraphQL Schema的可修改查询参数类型
核心问题拆解
1. 为什么之前的类型赋值会报只读错误
你用typeof generatedSchema.query.account_sample.__args获取类型时报Cannot assign to 'limit' because it is a read-only property,本质是TypeScript的默认推导规则导致的:
- 当一个对象通过
const导出时,TS会自动将其所有属性推导为带readonly修饰的类型,从根源上不允许对这个对象的属性做赋值修改,哪怕你没有手动写readonly关键字。 - 另外这个自动生成的
generatedSchema对象本质是GraphQL Schema的元数据映射,里面存的是SDL格式的类型字符串(比如'Int'、'[account_sample!]!'),和业务运行时实际使用的参数类型不属于同一个维度,哪怕绕开readonly限制拿到类型,也存在类型和实际用法不匹配的问题。
2. 从Query接口提取可复用参数类型的零重复写法
你提到的自动生成的Query接口是专门给业务运行时用的强类型定义,不需要手动重复写字段,借助TypeScript内置工具类型,一行就能提取出account_sample方法需要的入参类型:
// 定义独立的参数类型,和你手动声明的SuperArgs结构完全一致 type AccountSampleQueryArgs = NonNullable<Parameters<Query['account_sample']>[0]>;
这个写法的拆解:
Query['account_sample']:通过索引访问,拿到Query接口里account_sample方法本身的类型Parameters<T>:TS内置工具类型,专门用来提取函数类型的所有入参,组成一个元组类型[0]:因为account_sample方法只有1个入参(就是那个可选的查询参数对象),直接取元组的第0位NonNullable<T>:把这个入参本身的可选/可能为undefined的类型层剥掉,得到纯粹的参数对象类型
这个得到的类型没有任何readonly修饰,可以直接用来声明变量、自由修改属性:
// 正常赋值不会报类型错误 let params: AccountSampleQueryArgs = { limit: 400, offset: 0 }; params.where = { id: { _eq: 123 } };
关于从generatedSchema提取类型的兜底方案
如果你确实有需求要从generatedSchema那边拿可修改的类型,可以配合自定义的Mutable工具类型抹掉所有readonly修饰:
// 通用工具类型:移除对象所有属性的readonly修饰 type Mutable<T> = { -readonly [Key in keyof T]: T[Key] }; // 转成可修改的类型使用 let schemaParams: Mutable<typeof generatedSchema.query.account_sample.__args>; schemaParams.limit = 'Int'; // 注意这里的类型是SDL字符串,不是实际运行时的number
注:这个方案不推荐在业务代码中使用,因为拿到的类型是SDL元数据,和实际调用接口需要的JS参数类型不匹配,很容易引发类型偏差。
内容的提问来源于stack exchange,提问作者slumtrimpet
相关产品推荐
相关产品推荐

