简体   繁体   中英

Typescript - enforce collection contain only 2 types

I have a Product interface that has property items which is a collection that should accept only 2 types of items: ServiceTypeOne and ServiceTypeTwo .

This is what i came up with but i am not sure if this is the proper way to do it?

export interface Product{
   ...
   items: ProductItem<AcceptedServices>[];
   ...
}

export interface ProductItem<T extends AcceptedServices>{
   item:T;
   quantity:number;
}

export type AcceptedServices = ServiceTypeOne | ServiceTypeTwo;

Questions:

  1. Is there some better way that i'm missing?
  2. At later stage when i'll be iterating over Product.items i will want to check particular type of the item (if its underlying type is ServiceTypeOne or ServiceTypeTwo and based on type run some particular methods for that type). How to achieve that?

It seems that there's no point to use generics in ProductItem you can define it as:

export interface ProductItem {
    item: AcceptedServices;
    quantity: number;
}

I will want to check particular type of the item

You can define custom type guards :

type ServiceTypeOne = { type: 'one' };
type ServiceTypeTwo = { type: 'two' };

export interface Product {
    items: ProductItem[];
}

export interface ProductItem {
    item: AcceptedServices;
    quantity: number;
}

export type AcceptedServices = ServiceTypeOne | ServiceTypeTwo;

function isServiceTypeOne(item: AcceptedServices): item is ServiceTypeOne {
    return item.type === 'one';
}

function isServiceTypeTwo(item: AcceptedServices): item is ServiceTypeTwo {
    return item.type === 'two';
}

declare const product: Product;

for (const productItem of product.items) {
    if (isServiceTypeOne(productItem.item)) {
        // productItem.item is of type ServiceTypeOne
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM