代码之家  ›  专栏  ›  技术社区  ›  Josh Pittman

如何为React中的AWS amplify GraphQL响应设置typescript类型?

  •  0
  • Josh Pittman  · 技术社区  · 7 年前

    我在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 });
      }
    
      ...
    
    

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

    我发现 a similar problem 在AmplifyGitHub问题中,但该解决方案是在无状态功能组件的上下文中实现的。我使用的是有状态组件。

    上面的代码抛出 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<object>'

    最后,我尝试使用一个接口,如我发现的示例中所示:

    interface IListProjectQuery {
      projects: ListProjectsQuery;
    }
    

    然后我引用接口

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

    它抛出以下错误 Type '{ projects: null; }' is not assignable to type 'Readonly<{ projects: IListProjectQuery; }>'.

    为了让typescript高兴,我应该给默认state属性什么值?

    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,
    };
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Hackman    6 年前
    • 您必须定义一个类型,该类型与您期望从amplify获得的数据结构相匹配
    • 第二步是将响应数据转换为定义的类型,就这样。
    • 项目:IProject[]|未定义 . 您要么有一个项目数组,要么它是未定义的。

    export type IProject = {
        name: string
    }
    
    export type GetProjectsQuery = {
        listProjects:{
            items: IProject[]
        }
    }
    
    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
  •  0
  •   Mahmood Dehghan    7 年前

    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 });
      }