我如何在函数体中使用通用类型
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) => onOrderLoad(order)
或者只使用onOrderLoad
而不是handleOrderLoad
(在上面的示例中什么都不做,但委派给onOrderLoad
)
“其他人如何处理这种情况?” --- 在这种情况下,您的 OrderGuard
不是通用的。只需将其声明为const OrderGuard = (props: Props<Order>)
,我相信你会没事的。
@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
;
【讨论】:
以上是关于我如何在函数体中使用通用类型的主要内容,如果未能解决你的问题,请参考以下文章
如何修复上下文闭包类型 '((String, JSON), (String, JSON)) -> Bool' 需要 2 个参数,但在闭包体中使用了 1 个?