typescript - 自动生成的函数的Typesafe包装,然后仅通过使用 `__typename`作为参数来动态调用。 typescript

标签 typescript vue.js graphql graphql-codegen

我使用了真棒 graphql-codgen/vue 拥有完全类型安全的自动生成的代码。
我在我的项目中通过构建一些包装器来使用它,这样我的用户就不必在每次调用时都执行常见的配置任务。像定义缓存行为,自动更新缓存,以正确的类型和格式破坏结果。

使用JS和any的包装器工作程序,但我也希望它是类型安全的,并且因为graphql-codegen已经以类型安全的方式生成所有类型和方法,所以我认为必须有一种方法可以做到这一点。我以某种方式区别对待工会...

归结为示例代码,我的问题是:
我有这个自动生成的代码:

//File GQLService.ts
export type CustodiansList = (
  { __typename: 'Query' }
  & { custodiansList?: Maybe<Array<(
    { __typename: 'Custodian' }
    & Pick<Custodian, 'id' | 'name' | 'street' | 'zip' | 'city' | 'telephone' | 'createdAt' | 'updatedAt'>
  )>> }
);

type ReactiveFunctionCustodiansList = () => CustodiansListVariables

/**
 * __useCustodiansList__
 *
 * To run a query within a Vue component, call `useCustodiansList` and pass it any options that fit your needs.
 * When your component renders, `useCustodiansList` returns an object from Apollo Client that contains result, loading and error properties
 * you can use to render your UI.
 *
 * @param baseOptions options that will be passed into the query, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/query.html#options;
 *
 * @example
 * const { result, loading, error } = useCustodiansList(
 *   {
 *   }
 * );
 */
export function useCustodiansList(variables?: CustodiansListVariables | VueCompositionApi.Ref<CustodiansListVariables> | ReactiveFunctionCustodiansList, baseOptions?: VueApolloComposable.UseQueryOptions<CustodiansList, CustodiansListVariables>) {
          return VueApolloComposable.useQuery<CustodiansList, CustodiansListVariables>(CustodiansListDocument, variables, baseOptions);
        }

export type CustodiansListCompositionFunctionResult = ReturnType<typeof useCustodiansList>;


现在我想像这样以最少的DRY量“动态”使用它:

import * as Service from "./GQLService"; // from above
// e.g. typename = "custodian"
function useQueryList(typename:string) {
 const fnName = toFunctionName(typename) // e.g. useCustodiansList
 const result = Service[fnName](); //! this is the problem

 // we also want to return everything including a parsedResult 
 const listName = `${typename}sList`
 return {
    [listName]: parseResult(result),
    ...result
  }
}

即时

我真的不想像必须回答其他问题那样,通过创建区分的联合TypeTable来重新创建graphql-codgen完成的所有工作,因为我认为所有工作都已经由graphql-codegen完成。

我的目标是有人可以创建一个新的ExamplesList.graphqlgraphql-codegen对其进行包装,然后准备由useQueryList("example")使用

因此,尽管这是一个动态传递的参数,但还必须通过某种方式映射所有Service函数的返回类型,然后获取返回Array<__typename>的返回类型,来获取正确的静态类型,还是我错了?而且我认为我必须通过解析typename中所有可能的__typenames,将Service参数从字符串简化为字符串文字
const result = Service[fnName](); //! this is the problem

实际上,这并不是我们要做的所有事情,我们对其进行了包装和转换,但是一旦我在这里获得正确的类型,一切都会好起来的。

最佳答案

我认为这个问题与TypeScript而不是与GraphQL Codegen有关。
基本上,您要尝试的是从对象动态获取函数属性,我不确定如果不向Codegen输出中添加某些内容,TypeScript可能实现这一点。

您可以创建一个自定义codegen插件,该插件将根据您的所有查询生成一个对象,并带有您希望具有的单键(或者可能只是操作名称)。这样,您将能够获得"example"useExamplesListQuery之间的映射。

关于typescript - 自动生成的函数的Typesafe包装,然后仅通过使用 `__typename`作为参数来动态调用。 typescript ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61834756/

相关文章:

angular - 使用对象字面量作为 TypeScript 枚举值

validation - 对 v-for 生成的动态项目的 Element-UI 验证

javascript - 如何存储Firebase身份验证 session

vue.js - 如何将动态参数添加到 graphql 查询中

java - 如何在 GraphQL Java 上拆分模式

javascript - Angular 2 - 使用 HTML Canvas 时出现 "Cannot read property ' getContext' of null"错误

javascript - 热修复 "Type ' 字符串'不可分配给类型 'T'“?

angular - 错误 TS2531 对象在 Angular react 形式中可能为空

javascript - Vuejs Es6 类 react 性

reactjs - 我究竟做错了什么? - 未捕获的 TypeError : Object(. ..) 不是一个函数 - React GraphQL