以无缝方式使用打字稿联盟

时间:2017-09-14 10:54:34

标签: typescript unions

我正在谈论的后端有一个API来创建订单。 这样的订单有产品,当客户收到的产品只是由ID指定时,当服务器发送时,它们是完整的详细对象。

打字稿界面将是这样的:

export interface Order {
  userId: number;
  bought_products: BoughtProduct[];
}

export interface BoughtProduct {
  quantity: number;
  product: number | Product; // not specified here
  created?: string; // other keys are optional because only present if sent by Backend
}

如果打字稿解释器能够理解我将产品用作数字或接收产品作为对象,而没有明确的演员,那将是完美的。
这是因为,由于它是一个嵌套数组,使用强制转换会很复杂。

this playground link

中可以看到更直接的问题示例

2 个答案:

答案 0 :(得分:1)

如果你先输入格式,例如

,那么打字稿很聪明,可以自动为你播放
if (typeof boughtProduct.product === "number" {
     // it will be handled as number
} else {
     // it will be handled as Product
}

答案 1 :(得分:1)

我会做类似的事情:

interface Order {
    userId: number;
    bought_products: Array<ClientBoughtProduct | ServerBoughtProduct>;
}

interface BoughtProduct<T> {
    quantity: number;
    product: T;
}

interface ClientBoughtProduct extends BoughtProduct<number> {}

interface ServerBoughtProduct extends BoughtProduct<Product> {
    created: string;
}

然后我使用user defined type guards

function isClientBoughtProduct(obj: BoughtProduct<any>): obj is ClientBoughtProduct {
    return typeof obj.product === "number";
}

function isServerBoughtProduct(obj: BoughtProduct<any>): obj is ServerBoughtProduct {
    return typeof obj.product === "object";
}

if (isServerBoughtProduct(obj)) {
    // obj.created is available
}