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

Jos*_*man 2 amazon-web-services typescript reactjs aws-appsync aws-amplify

我在打字稿中有一个反应组件,我想将 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 });
  }

  ...

Run Code Online (Sandbox Code Playgroud)

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

我在 amplify github 问题中发现了类似的问题,但该解决方案是在无状态功能组件的上下文中。我正在使用有状态组件。

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

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

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

state = {
    projects: {listProjects: {items: [{name: ''}]}}
  }
Run Code Online (Sandbox Code Playgroud)

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

我要么被告知 a 要么被告知Property does not exist on type 'Observable<object>'默认状态值的形状不兼容。

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

interface IListProjectQuery {
  projects: ListProjectsQuery;
}
Run Code Online (Sandbox Code Playgroud)

然后我引用了接口

class App extends Component<
  {},
  {
    projects: IListProjectQuery;
  }
> 
Run Code Online (Sandbox Code Playgroud)

并引发以下错误 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,
};
Run Code Online (Sandbox Code Playgroud)

Hac*_*man 6

  • 您必须定义一个与您期望的数据结构相匹配的类型 amplify
  • 第二步是将您的响应数据转换为您定义的类型,就是这样。
  • 您的状态中的项目属性应该正确键入,项目: 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 
    }
Run Code Online (Sandbox Code Playgroud)