kib*_*ibe 11 pattern-matching typescript
在 F# 中,您可以执行以下操作:
type DeliveredOrderData =
{
OrderId: int;
DateDelivered: DateTime;
}
type UndeliveredOrderData =
{
OrderId: int;
}
type Order =
| Delivered of DeliveredOrderData
| Undelivered of UndeliveredOrderData
Run Code Online (Sandbox Code Playgroud)
然后我可以创建根据状态返回的函数:
let putOnTruck order =
match order with
| Undelivered {OrderId=id} ->
OutForDelivery {OrderId=id}
| Delivered _ ->
failwith "package already delivered"
Run Code Online (Sandbox Code Playgroud)
我了解了如何在 TypeScript 中创建类型,但是我该如何做与上面相同的事情呢?
const putOrderOnTruck = (order: UndeliveredOrder) => {
// how can I make sure order is really UndeliveredOrder?
}
Run Code Online (Sandbox Code Playgroud)
我们有两种不同类型的订单数据。区别在于,一个有DateDelivered,另一个没有。我们可以通过说UndeliveredOrderData可以never有 a DateDelivered(即该属性不得存在,或设置为undefined)来非常明确地表达这一点。
type DeliveredOrderData = {
OrderId: number;
DateDelivered: number;
}
type UndeliveredOrderData = {
OrderId: number;
DateDelivered?: never;
}
type Order = DeliveredOrderData | UndeliveredOrderData
Run Code Online (Sandbox Code Playgroud)
如果我们有一个Orderwhich可以是这两种类型中的任何一种,我们可以通过查看是否有a来判断它是哪种类型DateDelivered。我们将该逻辑放入用户定义的类型保护中,该保护告诉打字稿根据结果缩小类型范围。
const isDelivered = (order: Order): order is DeliveredOrderData => {
return !! order.DateDelivered;
}
Run Code Online (Sandbox Code Playgroud)
假设我们有一个函数需要UndeliveredOrderData
const doPutOnTruck = (order: UndeliveredOrderData) => {
}
Run Code Online (Sandbox Code Playgroud)
但在运行时,我们不确定 anOrder是否被传递。我们可以在语句中使用类型保护if,并在两个分支中采取不同的行为。
const maybePutOnTruck = (order: Order) => {
if ( isDelivered( order ) ) {
throw new Error("package already delivered");
}
// type of `order` is now `UndeliveredOrderData`
doPutOnTruck(order);
}
Run Code Online (Sandbox Code Playgroud)
TypeScript 的类型只能用于静态类型检查,因此为了做到这一点,您应该检查对象的属性。
这是一个例子
enum OrderType {
Delivered,
Undelivered
}
type DeliveredOrderData = {
type: OrderType
OrderId: number;
DateDelivered: Date
}
type UndeliveredOrderData = {
type: OrderType
OrderId: number;
}
function OutForDelivery(order: UndeliveredOrderData) {
}
let putOnTruck = (orderData: DeliveredOrderData | UndeliveredOrderData) => {
switch(orderData.type) {
case OrderType.Undelivered:
return OutForDelivery(orderData);
case OrderType.Delivered:
throw new Error('package already delivered');
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10870 次 |
| 最近记录: |