首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何定义支柱的类型,它是一个功能组件,同时指定FC的各种支柱类型

如何定义支柱的类型,它是一个功能组件,同时指定FC的各种支柱类型
EN

Stack Overflow用户
提问于 2021-06-29 04:40:24
回答 1查看 93关注 0票数 0

我有两个功能组件,它们有两种不同的道具类型。

代码语言:javascript
运行
复制
export interface OrderImageProps {
    orders: ICartItem[]
}

const OrderImage: React.FC<OrderImageProps> = (props: OrderImageProps) => {
    return (
        <div>
            // show some list
        </div>
    );
};

代码语言:javascript
运行
复制
export interface ProductImageProps {
    src: string
}

const ProductImage: React.FC<ProductImageProps> = (props: ProductImageProps) => {
    return (
        <Image className='img-fluid admin-product-image' src={props.src}/>
    );
};

这两个组件是表的实体,但有条件地呈现。因此,我需要将这两个组件传递给表组件。

代码语言:javascript
运行
复制
interface CustomDataTableProps {
    nameTag: string
    itemTag: string
    priceTag: string
    categoryTag: string
    dateTag: string
    actionsTag: string
    image: React.FC<ProductImageProps | OrderImageProps>
    list: boolean
}
    
const CustomDataTable: React.FC<CustomDataTableProps> = (props: CustomDataTableProps) => {
    const cartItems: ICartItem[] = useSelector((state: RootState): ICartItem[] => (state.cart.cartItems));
    const sampleData = sampleProducts.map((product: ICartItem) => {

    return {
        image: React.createElement(props.image, props.list ?
        {
            orders: cartItems
        } :
        {
            src: product.src
        }),
        // more data are in here
    };
}

但是当将道具传递给CustomDataTable时,它会显示FC<ProductImageProps> is not assignable to type FC<ProductImageProps | OrderImageProps>

我理解这个错误,显然它们是不兼容的类型。

据我理解,这些道具可能需要XOR类型的React.FC<>行为。

这可以很容易地通过在CustomDataTable上提供一个CustomDataTable来实现。还有其他一些表实体,它们具有类似于这种有条件呈现的组件。

我的第一种方法可以实现吗?还是使用渲染道具更好?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-29 07:29:38

React.FC本质上是一个带有额外步骤的函数类型。并在React.FC<P>中键入参数React.FC<P>位于负/反变位置。

当您尝试将image螺旋桨传递给CustomDataTable时,它会检查函数的兼容性,而当涉及到参数时,它会向相反的方向检查它们。当您将参数传递给React.FC<ProductImageProps>类型时,它不会检查ProductImageProps是否可分配给ProductImageProps | OrderImageProps,而是检查ProductImageProps | OrderImageProps是否可分配给ProductImageProps。显然不是。

image道具类型更改为React.FC<ProductImageProps> | React.FC<OrderImageProps>将消除以前的... is not assignable ...错误。但是您将在React.createElement呼叫站点上得到另一个错误。

现在,您的新props.image具有React.FC<ProductImageProps> | React.FC<OrderImageProps>类型。但是这种类型只接受ProductImageProps & OrderImageProps类型的参数。也就是说,拥有来自两种道具类型的所有必需字段。

代码语言:javascript
运行
复制
type PropsA = { a: string }
type PropsB = { b: string }

type A = (propsA: PropsA) => void
type B = (propsB: PropsB) => void

type AB = A | B

function fnFromAB(ab: AB): void { // ab has type (args: PropsA & PropsB) => void
    ab({ a: 'string' }) // error
    ab({ b: 'string' }) // error
    ab({ a: 'string ', b: 'string' }) // no error
}

操场链接

解决方案是使image组件的类型依赖于它的道具类型。由于道具的类型取决于list标志,所以您可以将代码重写为:

代码语言:javascript
运行
复制
type CustomDataTableProps = {
    nameTag: string
    itemTag: string
    priceTag: string
    categoryTag: string
    dateTag: string
    actionsTag: string
} & ({
    image: React.FC<OrderImageProps>
    list: true
} | {    
    image: React.FC<ProductImageProps>
    list: false
})
    
const CustomDataTable: React.FC<CustomDataTableProps> = (props: CustomDataTableProps) => {
    const cartItems: ICartItem[] = useSelector((state: RootState): ICartItem[] => (state.cart.cartItems));
    const sampleData = sampleProducts.map((product: ICartItem) => {

    const image = props.list
        ? React.createElement(props.image, { orders: cartItems })
        : React.createElement(props.image, { src: product.src })

    return {
        image,
        // more data are in here
    };
}

不幸的是,您将不得不重复React.createElement调用,因为props.image在三元操作符的每个分支中都有不同的类型。

当然,您可以使用类型断言来偷工减料。但为了类型安全的代价。像往常一样。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68172716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档