自动生成函数的类型安全包装,然后仅使用`__typename` 作为参数动态调用。打字稿

Joe*_*chr 5 typescript vue.js graphql graphql-codegen

我拥有由 awesome 完全类型安全的自动生成代码graphql-codgen/vue。我通过构建一个小包装器在我的项目中使用它,因此我的用户不必每次调用都执行常见的配置任务。例如定义缓存行为、自动更新缓存、以正确的类型和格式解构结果。

带有 JS 和 with 的包装器工人,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>;

Run Code Online (Sandbox Code Playgroud)

现在我想像这样“动态地”使用它,并使用最少的 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
  }
}
Run Code Online (Sandbox Code Playgroud)

意图

我真的不想通过创建一个有区别的联合来重新创建由 graphql-codgen 完成的所有工作,TypeTable就像在回答的其他一些问题中一样,因为我认为所有这些工作都已经由 graphql-codegen 完成了。

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

因此,虽然这是一个动态传递的参数,但它也必须能够通过某种方式映射所有服务函数的返回类型,然后获取返回 a 的那个,Array<__typename>或者我错了吗?而且我觉得我必须以某种方式不得不归结typename从字符串参数字符串文本解析所有候选条件__typenamesService

const result = Service[fnName](); //! this is the problem
Run Code Online (Sandbox Code Playgroud)

这实际上并不是我们所做的全部,我们对其进行了更多的包装和转换,但是一旦我在这里得到正确的类型,一切都应该没问题。

Dot*_*mha 3

我认为这个问题与 TypeScript 比与 GraphQL Codegen 更相关。基本上,您想要做的是动态地从对象获取函数属性,我不确定 TypeScript 是否可以在不向 codegen 输出添加某些内容的情况下实现这一点。

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