angular - 带有插值的 graphql-codegen 动态字段
问题描述
我正在使用graphql-codegen从 graphql 模式生成打字稿类型。我正在尝试创建一个带有动态字段的片段。
架构.ts
这是由 生成的类型graphql-codegen
。
/** User Type */
export type UserType = {
__typename?: 'UserType';
id: Scalars['ID'];
avatar: Scalars['String'];
email: Scalars['String'];
name: Scalars['String'];
showPostsInFeed: Scalars['Boolean'];
username: Scalars['String'];
};
用户模型.ts
我在整个应用程序中使用这些接口进行验证和一致性。
export interface IUserBase {
id: string;
avatar: string;
name: string;
username: string;
}
export interface IUserPost extends IUserBase {
showPostsInFeed: boolean;
}
export interface IUserProfile extends IUserBase, IUserPost {
email: string;
}
show.ts
这是用于生成的文件。在这里,我想使用我的existentIUserPost
和IUserProfile
接口制作一个带有动态字段的片段,以便重用这些字段并避免在片段中一一重复它们。
import gql from 'graphql-tag';
import { keys } from 'ts-transformer-keys';
import { IUserProfile, IUserPost } from '../../user.model';
const keysUserPofile = keys<IUserProfile>(); //Get all interface keys
const keysUserPost = keys<IUserPost>(); //Get all interface keys
//Fragments
export const fragments = {
userProfile: gql`
fragment UserProfile on UserType {
${keysUserPofile.join('\n')} //Interpolation
}
`,
userPost: gql`
fragment UserPost on UserType {
${keysUserPost.join('\n')} //Interpolation
}
`
};
//Queries
export const userProfileQuery = gql`
query UserProfileQuery($id: String!) {
showUser(id: $id) {
...UserProfile
}
}
`;
export const userPostQuery = gql`
query UserPostQuery($id: String!) {
showUser(id: $id) {
...UserPost
}
}
`;
当我尝试使用插值传递这些字段时,出现此错误:
$ npm run generate
> gogofans-ui@0.0.0 generate C:\Development\GogoFans\gogofans-ui
> graphql-codegen --config codegen.yml
√ Parse configuration
> Generate outputs
> Generate src/app/core/graphql/schema.ts
√ Load GraphQL schemas
× Load GraphQL documents
→ Syntax Error: Expected Name, found "}".
Generate
发现 1 个错误
× C:/Development/GogoFans/gogofans-ui/src/app/users/graphql/fragments/show.ts
GraphQLError: Syntax Error: Expected Name, found "}"。
在 Parser.expectToken (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\ language \ 的 syntaxError (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\error\syntaxError.js:15:10) parser.js:1423:40)
在 Parser.parseName (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:92:22)
在 Parser.parseField (C:\Development\GogoFans\ gogofans-ui\node_modules\graphql\language\parser.js:289:28)
在 Parser.parseSelection (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:278:81)
在 Parser .many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
在 Parser.parseSelectionSet (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\ parser.js:265:24)
在 Parser.parseFragmentDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:410:26)
在 Parser.parseDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\语言\parser.js:134:23)
在 Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
在 Parser.parseDocument (C:\Development\ GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:109:25)
在 Object.parse (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:36:17)
在 Object.parseGraphQLSDL (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\utils\index.cjs.js:601:28)
在 parseSDL (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\code-file-loader\index.cjs.js:239:18)
在 CodeFileLoader.load (C:\Development\GogoFans\gogofans- ui\node_modules@graphql-tools\code-file-loader\index.cjs.js:173:28)
在异步 loadFile (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\load\index.cjs .js:48:24)GraphQLError:语法错误:预期名称,找到“}”。
在 Parser.expectToken (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\ language \ 的 syntaxError (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\error\syntaxError.js:15:10) parser.js:1423:40)
在 Parser.parseName (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:92:22)
在 Parser.parseField (C:\Development\GogoFans\ gogofans-ui\node_modules\graphql\language\parser.js:289:28)
在 Parser.parseSelection (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:278:81)
在 Parser .many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
在 Parser.parseSelectionSet (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\ parser.js:265:24)
在 Parser.parseFragmentDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:410:26)
在 Parser.parseDefinition (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\语言\parser.js:134:23)
在 Parser.many (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:1537:26)
在 Parser.parseDocument (C:\Development\ GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:109:25)
在 Object.parse (C:\Development\GogoFans\gogofans-ui\node_modules\graphql\language\parser.js:36:17)
在 Object.parseGraphQLSDL (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\utils\index.cjs.js:601:28)
在 parseSDL (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\code-file-loader\index.cjs.js:239:18)
在 CodeFileLoader.load (C:\Development\GogoFans\gogofans- ui\node_modules@graphql-tools\code-file-loader\index.cjs.js:173:28)
在异步 loadFile (C:\Development\GogoFans\gogofans-ui\node_modules@graphql-tools\load\index.cjs .js:48:24)出问题了
npm 错误!代码 ELIFECYCLE
npm 错误!errno 1
npm 错误!gogofans-ui@0.0.0 生成:graphql-codegen --config codegen.yml
npm ERR!退出状态 1
npm ERR!
npm 错误!gogofans-ui@0.0.0 生成脚本失败。
npm 错误!这可能不是 npm 的问题。上面可能有额外的日志输出。npm 错误!可以在以下位置找到此运行的完整日志:
npm ERR!C:\Users\Fidel\AppData\Roaming\npm-cache_logs\2020-07-06T07_01_25_424Z-debug.log
解决方案
因为您的架构是静态的,所以字段不会改变。这意味着,您可以将所有可能的字段添加到您的选择集中,然后使用@skip
or@include
指令对其进行过滤。
GraphQL Codegen 及其使用的工具不支持字符串插值,也不会添加对它的支持,因为为了获得最终的字符串,我们需要加载、编译和查找导出的标识符。这样做会使 codegen 的设置变得更加复杂——因为 JS 生态系统中有许多不同的风格。
GraphQL 模式和操作可以定义为静态字符串,您应该能够使用指令或类似操作动态控制选择集。
这是一个在片段传播中使用内置指令@skip
和指令的示例:@include
query UserProfileQuery($id: String!, $loadA: Boolean, $loadB: Boolean) {
showUser(id: $id) {
...UserFieldsA @include(if: $loadA)
...UserFieldsB @include(if: $loadB)
}
}
fragment UserFieldsA {
id
a
}
fragment UserFieldsB {
id
b
}
这样,您可以在运行时通过设置变量$loadA
或$loadB
从您的 JS 代码动态控制它。
这些指令的定义与 GraphQL 中的定义类似:
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
这意味着您可以在字段、片段扩展或内联片段上使用它——因此它应该为您提供足够的灵活性来管理复杂和动态的选择集。
推荐阅读
- jmeter - 对于 Jmeter Bearer 授权令牌请求,获取 org.apache.http.conn.HttpHostConnectException
- python - 如何在 Tensorflow 中实现早期停止并降低高原学习率?
- node.js - NodeJS - TypeError:回调不是函数
- excel - 在 VBA 中删除多个 Excel 工作表
- sql - SQL获取一列中具有相同id但不同值的所有行
- stellar.js - 如何务实地将流明发送到未初始化的恒星地址
- c# - 无法使用 c sharp 创建基于事件的任务计划程序
- c++ - 无法打开栅格数据集
- javascript - 如何使用 javascript axios 转换此 curl 请求
- html - 尝试使用 CSS 实现响应式盒装结构