我如何在函数体中使用通用类型

Posted

技术标签:

【中文标题】我如何在函数体中使用通用类型【英文标题】:how i can use Generic type in function body 【发布时间】:2020-03-10 03:50:55 【问题描述】:

我正在尝试在组件 OrderGuard 中封装一些逻辑(它可以处理两种类型的订单:CheckinOrder | Checkout order,但是,当我尝试将订单传递给 orderLoad 回调时,打字稿开始抱怨这样

CheckinOrder 可分配给类型 T 的约束,但 T 可以使用不同的子类型约束 'Order' 进行实例化

type Order = CheckoutOrder | CheckinOrder;

interface Props<T extends Order> 
    orderId: string;
    orderLoaded: boolean;
    onOrderLoad: (order: T) => void;
    loadOrder: UseCheckinOrder | UseCheckoutOrder;
    children?: React.ReactElement;


const isCheckinOrder = (order: Order): order is CheckinOrder => 
    return !('servicesFallbackURL' in order);
;

const OrderGuard: <T extends Order>(props: Props<T>) => React.ReactElement<Props<T>> = (
    orderId,
    orderLoaded,
    onOrderLoad,
    loadOrder,
    children
) => 
    const [userHasAccess, setUserHasAccess] = useState(true);
    const  refetch, loading  = loadOrder(orderId,  skip: true );

    const handleOrderLoad = (order: Order) => 
        if (isCheckinOrder(order)) 
            onOrderLoad(order as CheckinOrder); // <-- error here
         else 
            onOrderLoad(order as CheckoutOrder); // <-- and here
        
    ;

我想我错过了一些东西,但不知道是什么 我是打字稿的新手,其他人如何处理这种情况?

组件调用看起来像

    <OrderGuard<CheckoutOrder>
        orderId=orderId
        orderLoaded=!!order
        onOrderLoad=fillOrder
        loadOrder=useOrder
    >
        <Checkout startNewSearch=startNewSearch />
    </OrderGuard>

【问题讨论】:

相关:***.com/q/56505560/251311 你不能只使用const handleOrderLoad = (order: T) =&gt; onOrderLoad(order) 或者只使用onOrderLoad 而不是handleOrderLoad(在上面的示例中什么都不做,但委派给onOrderLoad “其他人如何处理这种情况?” --- 在这种情况下,您的 OrderGuard 不是通用的。只需将其声明为const OrderGuard = (props: Props&lt;Order&gt;),我相信你会没事的。 @AlekseyL。不,当我尝试将订单传递给 onOrderLoad 函数 dropmefiles.com/SFio7 时,我遇到了同样的错误 不需要类型断言,因为你已经在它前面放置了一个类型保护函数。 【参考方案1】:

不使 Prop 接口通用将解决您在这种情况下的问题。

type Order = CheckoutOrder | CheckinOrder;

interface Props 
    orderId: string;
    orderLoaded: boolean;
    onOrderLoad: (order: Order) => void;
    loadOrder: UseCheckinOrder | UseCheckoutOrder;
    children?: React.ReactElement;


const isCheckinOrder = (order: Order): order is CheckinOrder => 
    return !('servicesFallbackURL' in order);
;

const OrderGuard: (props: Props) => React.ReactElement<Props> = (
    orderId,
    orderLoaded,
    onOrderLoad,
    loadOrder,
    children
) => 
    const [userHasAccess, setUserHasAccess] = useState(true);
    const  refetch, loading  = loadOrder(orderId,  skip: true );

    const handleOrderLoad = (order: Order) => 
        if (isCheckinOrder(order)) 
            onOrderLoad(order); // <-- no need to cast
         else 
            onOrderLoad(order as CheckoutOrder); // <-- no more errors
        
    ;

【讨论】:

以上是关于我如何在函数体中使用通用类型的主要内容,如果未能解决你的问题,请参考以下文章

如何从函数返回数据类型 int** 并存储它?

matlab中如何看函数结构体中的数据

如何修复上下文闭包类型 '((String, JSON), (String, JSON)) -> Bool' 需要 2 个参数,但在闭包体中使用了 1 个?

如何复制一个含qstring的结构体

通用函数和类型如何存储在 rlib 中?

如何在具有通用参数类型的接口中实现函数?