【问题标题】:How do I set typescript types for an AWS amplify GraphQL response in React?如何在 React 中为 AWS 放大 GraphQL 响应设置打字稿类型?
【发布时间】:2019-02-09 06:58:14
【问题描述】:

我在 typescript 中有一个 react 组件,我想将 appsync graphql 查询的结果设置为 state 中的属性。

import React, { Component } from 'react';
import { API, graphqlOperation } from 'aws-amplify';
import {ListProjectsQuery} from './API'
import {listProjects } from './graphql/queries';

class App extends Component<{}, {
  projects:ListProjectsQuery
}>  {
  state = {
    projects: null
  };
  async componentDidMount() {
    const projects = await API.graphql(graphqlOperation(listProjects));
    this.setState({ projects });
  }

  ...

如何定义默认状态属性以使其工作?

我在放大 github 问题中找到了 a similar problem,但该解决方案是在无状态功能组件的上下文中。我正在使用有状态组件。

根据我的尝试,我似乎遇到了三个错误之一。

上面的代码抛出Type 'null' is not assignable to type 'ListProjectsQuery'.

这是有道理的,所以我尝试将形状映射为如下状态:

state = {
    projects: {listProjects: {items: [{name: ''}]}}
  }

这使它抛出Types of property 'projects' are incompatible.

我要么被告知Property does not exist on type 'Observable&lt;object&gt;',要么被告知默认状态值的形状不兼容。

最后我尝试使用我找到的示例中的界面:

interface IListProjectQuery {
  projects: ListProjectsQuery;
}

然后我引用接口

class App extends Component<
  {},
  {
    projects: IListProjectQuery;
  }
> 

它会抛出以下错误Type '{ projects: null; }' is not assignable to type 'Readonly&lt;{ projects: IListProjectQuery; }&gt;'.

我应该赋予默认状态属性什么值才能让 typescript 满意?

ListProjectsQuery 导入由 amplify/appsync codegen 自动生成,类型别名如下所示:

export type ListProjectsQuery = {
  listProjects:  {
    __typename: "ModelProjectConnection",
    items:  Array< {
      __typename: "Project",
      id: string,
      name: string,
      organisation:  {
        __typename: "Organisation",
        id: string,
        name: string,
      } | null,
      list:  {
        __typename: "ModelListConnection",
        nextToken: string | null,
      } | null,
    } | null > | null,
    nextToken: string | null,
  } | null,
};

【问题讨论】:

    标签: reactjs typescript amazon-web-services aws-appsync aws-amplify


    【解决方案1】:
    • 您必须定义一个与您期望从放大中获得的数据结构相匹配的类型
    • 第二步是将响应数据转换为您定义的类型,仅此而已。
    • 您所在州的项目属性应正确键入,projects: IProject[ ] |未定义。您要么有一个项目数组,要么是未定义的。

    export type IProject = {
        name: string
    }
    
    export type GetProjectsQuery = {
        listProjects:{
            items: IProject[]
            nextToken: string
        }
    }
    
    const fetchAllProjects = async () => {
        try {
          const result = (await API.graphql(graphqlOperation(queries.listProjects))) as {
            data: GetProjectsQuery
          }
          projects = result.data.listProjects.items
          
    
        } catch (error) {
          //handle error here 
        }

    【讨论】:

      【解决方案2】:

      使您的属性可选:

      class App extends Component<{}, {
        projects?: ListProjectsQuery //<<== note the question mark
      }>  {
        state = {
          projects: null
        };
        async componentDidMount() {
          const projects = await API.graphql(graphqlOperation(listProjects));
          this.setState({ projects });
        }
      

      【讨论】:

      • 谢谢。不幸的是,这没有帮助。它抛出 Property 'state' in type 'App' is not assignable to the same property in base type 'Component&lt;{}, { projects?: ListProjectsQuery | undefined; }, any&gt;'. 所以在组件状态下将 null 切换为 undefined 然后它又回到抛出 Types of property 'projects' are incompatible.
      • 后者的完整错误日志是:``` Type error: Argument of type '{ projects: GraphQLResult |可观察的; }' 不可分配给类型为 '{ projects?: ListProjectsQuery | 的参数不明确的; } | ((prevState: Readonly, props: Readonly) => { projects?: ListProjectsQuery | undefined; } | Pick<...> | null) |选择<...> |空值'。类型 '{ 项目:GraphQLResult |可观察的; }' 不可分配给类型 'Pick'。 ``` 继续...
      • ```属性“项目”的类型不兼容。输入'GraphQLResult | Observable' 不可分配给类型 'ListProjectsQuery |不明确的'。 “GraphQLResult”类型中缺少属性“listProjects”,但在“ListProjectsQuery”类型中是必需的。 TS2345``````
      • 要么像 const projects = await API.graphql(graphqlOperation(listProjects)) 那样手动转换结果类型为 ListProjectsQuery;或者 。您必须在结果中添加另一种类型,因为有可能,查询无法解析,然后该类型将不是 ListProjectsQuery 类型,而是未定义,或者例如错误类型。
      • 很遗憾我也遇到了这个问题。我认为答案可能是不使用async / await.. 那么您应该能够更轻松地输入它吗?我想我会做出回应..
      猜你喜欢
      • 1970-01-01
      • 2018-04-26
      • 2020-08-09
      • 1970-01-01
      • 2020-05-29
      • 2021-02-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      相关资源
      最近更新 更多