如何在React中为AWS放大GraphQL响应设置typescript类型



我在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问题中发现了类似的问题,但该解决方案是在无状态功能组件的上下文中提出的。我正在使用一个有状态组件。

根据我的尝试,我似乎会犯三个错误中的一个。

上面的代码抛出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,
};
  • 您必须定义一个与您期望放大的数据结构匹配的类型
  • 第二步是将响应数据强制转换为您定义的类型,仅此而已
  • 您所在州的projects属性应正确键入,projects:IProject[]| undefined。你要么有一个项目数组,要么它是未定义的

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 
}

使您的属性可选:

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

最新更新