如何在React中为AWS放大GraphQL响应设置打字稿类型?

时间:2019-02-09 06:58:15

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

我在打字稿中有一个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<object>',或者被告知默认状态值的形状不兼容。

最后,我尝试使用类似我发现的示例的界面:

interface IListProjectQuery {
  projects: ListProjectsQuery;
}

然后我引用界面

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

并引发以下错误Type '{ projects: null; }' is not assignable to type 'Readonly<{ projects: IListProjectQuery; }>'.

我应赋予默认状态属性什么值,以使打字稿快乐?

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

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

2 个答案:

答案 0 :(得分:1)

  • 您必须定义一个与您希望放大的数据结构相匹配的类型
  • 第二步是将响应数据转换为您定义的类型,就是这样。
  • 应正确键入州内的项目属性,项目: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 
    }

答案 1 :(得分:0)

将您的媒体资源设置为可选

_, err = con.Query(`
    DELETE FROM loan_aims WHERE _loan = $1;
`, input.ID)
if err != nil {
    tx.Rollback()
    log.Println(err)
    return false, fmt.Errorf("can not delete additional data from loan_aims")
}