Shamoon
Shamoon

Reputation: 43639

How can I make a TypeScript interface be one of 2 possible types where one is an array?

I am trying:

type SkuItem = ChildSkuItem & {
    childSkus: ChildSkuItem[],
};

type GetSkuItemsResponseType = Partial<Array<SkuItem>> & {
    errorCode?: string;
    errorMessage?: string;
}

Partial<GetSkuItemsErrSkuResponse> { }
export interface GetSkuItemsResponse extends GetSkuItemsResponseType { }

So GetSkuItemsResponse can either be an array of SkuItem or an object with properties errorCode and errorMessage.

However, this doesn't seem to work as I get:

 Argument of type '{ errorCode: string; errorMessage: string; }' is not assignable to parameter of type 'GetSkuItemsResponse'.
  Type '{ errorCode: string; errorMessage: string; }' is missing the following properties from type 'GetSkuItemsResponse': length, pop, push, concat, and 26 more.

Upvotes: 1

Views: 189

Answers (1)

Rich N
Rich N

Reputation: 9475

@shamoon - your type is fine for what you want if you use 'or' (|) instead of 'and' (&). However, you can't then make it an interface, because classes can implement interfaces and can't easily implement one or other of two possible types. Consider the code below - isn't this what you want?

interface ChildSkuItem {
    id: number;
    value?: string;
}
type SkuItem = ChildSkuItem & {
    childSkus: ChildSkuItem[],
};
type GetSkuItemsResponseType = Partial<Array<SkuItem>> | {
    errorCode?: string;
    errorMessage?: string;
}
// Can't make GetSkuItemsResponseType into an interface with this definition...
//interface GetSkuItemsResponse extends GetSkuItemsResponseType { }

function test() {
    const sku1: ChildSkuItem = { id: 1, value: "A Value" };
    const sku2: ChildSkuItem = { id: 2 };
    const sku3: ChildSkuItem = { id: 3 };
    const skuItem1: SkuItem = { id: 104, childSkus: [sku1, sku2] };
    const skuItem2: SkuItem = { id: 105, childSkus: [sku3] };
    // GetSkuItemsResponseType can have error info...
    const rt: GetSkuItemsResponseType = { errorCode: "100", errorMessage: "screwed" };
    // ...or it can have an array of skuItems
    const rt2: GetSkuItemsResponseType = [skuItem1, skuItem2];
};

Upvotes: 1

Related Questions