【问题标题】:How to use Graphql typescript types in react如何在反应中使用 Graphql 打字稿类型
【发布时间】:2021-12-30 07:58:30
【问题描述】:

我有一个带有 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;

我想创建一个Product 组件,而不是使用&lt;div&gt;{product?.name}&lt;/div&gt;

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

那么在传递产品的时候,产品页面的类型应该是什么

【问题讨论】:

    标签: reactjs typescript graphql


    【解决方案1】:

    解决方案

    您可以通过如下更改代码来修复错误:

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

    由于所有属性如 namedescription 丢失,Typescript 抱怨它。这是一个有效的codesandbox 供您查看。

    【讨论】:

      【解决方案2】:

      以下内容对您有用吗?

      interface ProductComponentProps {
          product: ProductData_allProducts
      }
      
      
      const Product = ({product}: ProductComponentProps) => {
          return (
              <p>{product.name}</p>
          );
      };
      
      

      【讨论】:

      • 确实有效,但这些类型是由apollo codegen 生成的,所以我认为我不应该做这样的事情
      • 我在哪里使用组件并传入product 我得到Type 'ProductData_allProducts | null' is not assignable to type 'ProductData_allProducts'. Type 'null' is not assignable to type 'ProductData_allProducts'.
      【解决方案3】:

      您正在尝试解构该类型上不存在的属性。
      这应该有效:

      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;
      

      【讨论】:

      • 我使用的是product 而不是name,但我仍然收到Property 'product' does not exist on type 'PropsWithChildren&lt;ProductData_allProducts&gt;'
      • 我用的是ProductData_allProducts而不是你的Product,因为它们是一样的
      • 是的,您可以使用您的类型(相同)
      • 但我仍然遇到同样的错误
      猜你喜欢
      • 1970-01-01
      • 2020-11-10
      • 2018-03-27
      • 2017-06-24
      • 2021-08-05
      • 2020-08-09
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多