Ever Dev
Ever Dev

Reputation: 2142

How to define a type for a template in TypeScript?

I'm going to define a type where I can store the response from various API that has similar responses.

The response looks like

type TResponse<E> = {
   Code: number;
   Message: string;
   Result: {
      [i: string]:  Array<E>;
      Count: number;
   };
   Status: string;
}

[i: string] can be anything except for Count depending on the API design, for example, Rows, Values, Logs, etc...
This for now gives me an error, because of the Count property conflicts with [i: string].

P.S. I'm using the typescript version ^3.9.7

Upvotes: 0

Views: 1699

Answers (1)

Lauren Yim
Lauren Yim

Reputation: 14078

You can use an intersection type:

type TResponse<E> = {
   Code: number;
   Message: string;
   Result: {
      [i: string]: Array<E>;
    } & {
      Count: number;
   };
   Status: string;
}

declare const response: TResponse<string>;
response.Result.Count; // number
response.Result.abc; // string[]

Note that this is slightly unsafe, which is why TS requires that all properties are assignable to its index signature:

declare const key: string;
response.Result[key]; // string[] even though key could be Count

Also, trying to create objects like this requires a type assertion:

const response2: TResponse<string> = {
   Code: 0,
   Message: '',
   // Type '{ Count: number; }' is not assignable to type ...
   Result: {
      Count: 1
   },
   Status: ''
}

const response3 = {
   Code: 0,
   Message: '',
   Result: {
      Count: 1
   },
   Status: ''
} as TResponse<string>

Playground link

Upvotes: 2

Related Questions