marzzy
marzzy

Reputation: 788

How to define a type with some optional specified properties along side some required specified ones in Typescript

I have the below object:

const colors: tColors = {
  dark: {
     main: {
       normal: '#022c43', dark30: '#011f2f', light30: '#4e6b7b', contrastColor: '#fff',
     },
     secound: {
       normal: '#053f5e', dark30: '#042c42', light30: '#add6de', contrastColor: '#fff',
     },
     error: { normal: '#d32f2f', contrastColor: '#fff' },
     success: { normal: '#388e3c', contrastColor: '#fff' },
  },
  light: {
     main: {
       normal: '#28527a', dark30: '#1c3955', light30: '#6986a2', contrastColor: '#fff',
     },
     secound: {
       normal: '#8AC4D0', dark30: '#618992', light30: '#50798e', contrastColor: '#fff',
     },
     error: { normal: '#e57373', contrastColor: '#000' },
     success: { normal: '#81c784', contrastColor: '#000' },
  },
};

I define tColors like:

type tColors = {
  [themeKey in 'light' | 'dark']: {
    [key : string]: {
       [shadeKey: string ]: string
    }
  }
};

it works but if I want to limit the shadeKey like this:

shadekey in 'normal' | 'dark30' | 'light30' | 'contrastColor'

it gives me some errors on error and success fields, the errors are:

Type '{ normal: string; contrastColor: string; }' is missing the following properties from type '{ normal: string; dark30: string; light30: string; contrastColor: string; }': dark30, light30

the problem is I don't want to add dark30 or light30 in error and success fields but I want the shadekey to be sensitive about other keys

Is there any way that I can set the dark30 and light30 as optional properties, but the rest of them stay the same?

Upvotes: 1

Views: 54

Answers (1)

Wang Weixuan
Wang Weixuan

Reputation: 351

Since shadeKey values are known and limited, you can write them as properties instead of index signatures:

type tColors = {
  [themeKey in "light" | "dark"]: {
    [key: string]: {
      normal: string;
      dark30?: string;
      light30?: string;
      contrastColor: string;
    };
  };
};

Here ? after dark30 and light30 suggests that the property is optional.

Upvotes: 1

Related Questions