Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript object with [key: string]: string | string[]

I have a type defined as follows:

type IColumn = {
  name: string;
  key: string;
  attributes: { [key: string]: string | string[] };
  shortable: boolean;
};

The only field of attributes that can be string[] is called options

So I would like to do something of the type:

type IColumn = {
  name: string;
  key: string;
  attributes: { [key: string]: string ; options: string[] };
  shortable: boolean;
};

To avoid having to specify at each use of attributes whether it is string or string[]. But this does not work.

Is there a way to make it?

like image 543
Alberto Valero Avatar asked Aug 12 '26 12:08

Alberto Valero


1 Answers

Index signature like that requires that every possible value matches that signature. If you want that as a fallback you have to do an intersection with a in string signature:

type IColumn = {
  name: string;
  key: string;
  attributes: { [key in string]: string }
    & { options: string[] };
  shortable: boolean;
};

Or using the nice aliases in the standard library:

type IColumn = {
  name: string;
  key: string;
  attributes: Record<string, string> & { options: string[] };
  shortable: boolean;
};

If you think you might have this pattern in multiple places you can make a helper type like this:

export type WithDefault<Default, T extends Record<string, any>> = Record<string, Default> & T;

type IColumn = {
  name: string;
  key: string;
  attributes: WithDefault<string, {
    options: string[],
    someFlag: boolean,
  }>;
  shortable: boolean;
};
like image 140
Luiz Ferraz Avatar answered Aug 20 '26 05:08

Luiz Ferraz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!