GraphQL 查询返回类型的“任何”数据类型
Posted
技术标签:
【中文标题】GraphQL 查询返回类型的“任何”数据类型【英文标题】:"Any" data type for GraphQL Query Return Type 【发布时间】:2020-07-05 05:04:48 【问题描述】:我对 Typescript 有点陌生,并且在数据类型方面遇到了一些问题。有人告诉我应该避免使用“任何”数据类型,因为它否定了使用 Typescript 的全部意义。但是,我无法更改数据类型。例如,
当我运行 GraphQL 查询时,我使用这个:
login(
variables:
email: email,
password: password,
,
)
.then(( data : any) =>
localStorage.setItem('token', data.loginEmail.accessToken);
setShouldRedirect(true);
//props.history.push("/panel");
)
data.loginEmail.accessToken
是一个字符串,所以我将 :any
更改为字符串,但出现以下错误:
Argument of type '( data : string) => void' is not assignable to parameter of type '(value: ExecutionResult<any>) => void | PromiseLike<void>'.
Types of parameters '__0' and 'value' are incompatible.
Type 'ExecutionResult<any>' is not assignable to type 'string'. TS2345
如果我将类型更改为object
,我会得到Property 'data' does not exist on type ''. TS2339
,但文档还说突变返回一个对象。因此,如果不是对象或字符串,我还能如何指定此类对象的数据类型?有可能吗?
同样,当我在查询后映射这样的项目时:
data &&
data.users.nodes &&
data.users.nodes.map((c: any, i: any) => (
<li key=i>
Id: c.id, First Name: c.firstName, Last Name: c.lastName,
Email: c.email, phoneNumber: c.phoneNumber
</li>
))
我还能如何指定 c 和 I? i 没有简单的整数选项。
编辑:
架构:
loginEmail(
email: String!
password: String!
): SignInResponse!
type SignInResponse
accessToken: String!
GraphQL 代码:
export type MutationLoginEmailArgs =
email: Scalars['String'],
password: Scalars['String']
;
【问题讨论】:
试试改成.then(( data : ExecutionResult<data:string;>) =>
data : string
没有意义。字符串不是具有.data
属性的对象
@NickSurmanidze 这给了我一个关于data.loginEmail
的错误property loginEmail doesn't exist on type data:string
我也尝试过对象但仍然是同样的问题
是的,你是对的。狂野没用的尝试。 @Bergi 认为由于突变中的两种类型都是字符串,也许有某种方法可以将字符串传递两次?记住这个问题的答案
【参考方案1】:
看起来你的数据结构对应如下类型接口:
interface MyDataReponse
users:
nodes:
id: string; // maybe this is number in your case
firstName:string;
lastName: string;
phoneNumber: string;
email: string;
[]
然后在你的数据上:
.then(( data : ExecutionResult<data:MyDataReponse;>) =>
【讨论】:
它仍然在下一行的 loginEmail 上给出相同的错误。不同之处在于它说MyDataReponse
而不是字符串
你知道如何解决这个问题吗?【参考方案2】:
如果你使用 TypeScript,你应该为钩子返回的数据和你传递给它的变量生成类型。可以使用Apollo CLI 或GraphQL Code Generator 来生成类型。
一旦你有了你的类型,你就可以将它们与你的钩子一起使用,如here in the docs所示。通过这样做,您将避免在使用挂钩返回的 data
属性时显式分配类型。您还将为传递给钩子的任何变量添加类型安全性。
文档中的示例用法:
interface RocketInventory
id: number;
model: string;
year: number;
stock: number;
interface RocketInventoryData
rocketInventory: RocketInventory[];
interface RocketInventoryVars
year: number;
const GET_ROCKET_INVENTORY = gql`
query getRocketInventory($year: Int!)
rocketInventory(year: $year)
id
model
year
stock
`;
export const SomeComponent = () =>
const loading, data = useQuery<RocketInventoryData, RocketInventoryVars>(
GET_ROCKET_INVENTORY,
variables: year: 2019
);
...
【讨论】:
我还是有点迷茫。我尝试了您建议的工具并使用输出编辑了 qs。但是,我仍然不知道如何在我的代码中使用它们。我应该在我的代码中只使用interface LoginEmail email: string; password:string;
吗?但我的问题是我如何才能完全改变data: any
通过将正确的类型传递给 useQuery
钩子,TypeScript 将能够推断 data
的类型,而您可以执行其他任何操作。以上是关于GraphQL 查询返回类型的“任何”数据类型的主要内容,如果未能解决你的问题,请参考以下文章
我应该如何确定查询返回到 GraphQL 接口类型的显式类型?