如何在 React 中使用 Graphql typescript 类型
How to use Graphql typescript types in react
我有一个带有 keystone.js 后端和 graphql api
的 React 应用程序
我在 keystones.js 中有一个产品列表和一个简单的 graphql 查询
import gql from "graphql-tag";
export const ALL_PRODUCTS_QUERY = gql`
query ProductData{
allProducts{
id
price
description
name
}
}
`
我正在使用 apollo codegen 生成 graphql 的类型,所以我得到
export interface ProductData_allProducts {
__typename: "Product";
id: string;
price: number | null;
description: string | null;
name: string | null;
}
export interface ProductData {
/**
* Search for all Product items which match the where clause.
*/
allProducts: (ProductData_allProducts | null)[] | null;
}
在 React 中我可以列出产品并使用代码中的类型,这里我使用 <ProductData>
import { useQuery } from "@apollo/client";
import {ALL_PRODUCTS_QUERY} from '../queries/index'
import { ProductData } from "../generated/ProductData";
const Products = () => {
const {data, error, loading} = useQuery<ProductData>(ALL_PRODUCTS_QUERY)
if(loading) return <p>Loading</p>
if(error) return <p>Error: {error.message}</p>
return (
<div>
<div>
{data?.allProducts?.map(product => (
<div>{product?.name}</div>
))}
</div>
</div>
);
};
export default Products;
而不是使用 <div>{product?.name}</div>
我想创建一个 Product
组件
import React from 'react';
import { ProductData, ProductData_allProducts } from '../generated/ProductData';
const Product = ({product}:ProductData_allProducts) => {
return (
<p>{product.name}</p>
);
};
export default Product;
但是 product
的类型应该是什么 我收到一条错误消息说
Property 'product' does not exist on type 'ProductData_allProducts'.
在产品页面上
import { useQuery } from "@apollo/client";
import {ALL_PRODUCTS_QUERY} from '../queries/index'
import { ProductData } from "../generated/ProductData";
import Product from "./Product";
const Products = () => {
const {data, error, loading} = useQuery<ProductData>(ALL_PRODUCTS_QUERY)
if(loading) return <p>Loading</p>
if(error) return <p>Error: {error.message}</p>
return (
<div>
<div>
{data?.allProducts?.map(product => (
<Product product={product} />
))}
</div>
</div>
);
};
export default Products;
我现在在产品道具上遇到错误
Type '{ product: ProductData_allProducts | null; }' is not assignable to type 'IntrinsicAttributes & ProductData_allProducts'.
Property 'product' does not exist on type 'IntrinsicAttributes & ProductData_allProducts'.
那么传入产品时,产品页面上的类型应该是什么
您正在尝试解构类型上不存在的 属性。
这应该有效:
type Product = {
__typename: "Product";
id: string;
price: number | null;
description: string | null;
name: string | null;
};
const ProductComponent: FC<Product> = ({ name }) => {
return <p>{name}</p>;
};
export default ProductComponent;
以下对你有用吗?
interface ProductComponentProps {
product: ProductData_allProducts
}
const Product = ({product}: ProductComponentProps) => {
return (
<p>{product.name}</p>
);
};
解决方案
您可以像这样更改代码来修复错误:
const Product = ({ product }: { product: ProductData_allProducts }) => {
return <p>{product.name}</p>;
};
说明
问题是您将组件的 props
键入为类型 ProductComponentProps
,而您一直只想键入 属性 props.product
。所以你的代码基本上是这样的:
const Product = (props: ProductData_allProducts) => {
return (
<p>{product.name}</p>
);
};
由于缺少 name
或 description
等所有属性,Typescript 对此进行了投诉。这是一个工作 codesandbox 供您查看。
我有一个带有 keystone.js 后端和 graphql api
的 React 应用程序我在 keystones.js 中有一个产品列表和一个简单的 graphql 查询
import gql from "graphql-tag";
export const ALL_PRODUCTS_QUERY = gql`
query ProductData{
allProducts{
id
price
description
name
}
}
`
我正在使用 apollo codegen 生成 graphql 的类型,所以我得到
export interface ProductData_allProducts {
__typename: "Product";
id: string;
price: number | null;
description: string | null;
name: string | null;
}
export interface ProductData {
/**
* Search for all Product items which match the where clause.
*/
allProducts: (ProductData_allProducts | null)[] | null;
}
在 React 中我可以列出产品并使用代码中的类型,这里我使用 <ProductData>
import { useQuery } from "@apollo/client";
import {ALL_PRODUCTS_QUERY} from '../queries/index'
import { ProductData } from "../generated/ProductData";
const Products = () => {
const {data, error, loading} = useQuery<ProductData>(ALL_PRODUCTS_QUERY)
if(loading) return <p>Loading</p>
if(error) return <p>Error: {error.message}</p>
return (
<div>
<div>
{data?.allProducts?.map(product => (
<div>{product?.name}</div>
))}
</div>
</div>
);
};
export default Products;
而不是使用 <div>{product?.name}</div>
我想创建一个 Product
组件
import React from 'react';
import { ProductData, ProductData_allProducts } from '../generated/ProductData';
const Product = ({product}:ProductData_allProducts) => {
return (
<p>{product.name}</p>
);
};
export default Product;
但是 product
的类型应该是什么 我收到一条错误消息说
Property 'product' does not exist on type 'ProductData_allProducts'.
在产品页面上
import { useQuery } from "@apollo/client";
import {ALL_PRODUCTS_QUERY} from '../queries/index'
import { ProductData } from "../generated/ProductData";
import Product from "./Product";
const Products = () => {
const {data, error, loading} = useQuery<ProductData>(ALL_PRODUCTS_QUERY)
if(loading) return <p>Loading</p>
if(error) return <p>Error: {error.message}</p>
return (
<div>
<div>
{data?.allProducts?.map(product => (
<Product product={product} />
))}
</div>
</div>
);
};
export default Products;
我现在在产品道具上遇到错误
Type '{ product: ProductData_allProducts | null; }' is not assignable to type 'IntrinsicAttributes & ProductData_allProducts'.
Property 'product' does not exist on type 'IntrinsicAttributes & ProductData_allProducts'.
那么传入产品时,产品页面上的类型应该是什么
您正在尝试解构类型上不存在的 属性。
这应该有效:
type Product = {
__typename: "Product";
id: string;
price: number | null;
description: string | null;
name: string | null;
};
const ProductComponent: FC<Product> = ({ name }) => {
return <p>{name}</p>;
};
export default ProductComponent;
以下对你有用吗?
interface ProductComponentProps {
product: ProductData_allProducts
}
const Product = ({product}: ProductComponentProps) => {
return (
<p>{product.name}</p>
);
};
解决方案
您可以像这样更改代码来修复错误:
const Product = ({ product }: { product: ProductData_allProducts }) => {
return <p>{product.name}</p>;
};
说明
问题是您将组件的 props
键入为类型 ProductComponentProps
,而您一直只想键入 属性 props.product
。所以你的代码基本上是这样的:
const Product = (props: ProductData_allProducts) => {
return (
<p>{product.name}</p>
);
};
由于缺少 name
或 description
等所有属性,Typescript 对此进行了投诉。这是一个工作 codesandbox 供您查看。