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

How do I set typescript types for an AWS amplify GraphQL response in React?

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

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; }>'.

我给默认状态 属性 什么值才能使 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,
};

使您的 属性 可选:

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 });
  }
  • 您必须定义一个与您期望从 amplify 获得的数据结构相匹配的类型
  • 第二步是将您的响应数据转换为您定义的类型,仅此而已。
  • 您所在州的项目 属性 应该正确输入,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 
    }