Search code examples
javascriptreactjstypescriptobjectobject-literal

TypeScript: Access specific key of excluded readonly object literal


I need to ensure that the value of bar must be a label of either of the keys except c and d in a read-only object FOO.

const FOO = {
  a: {
    label: 'aa',
    value: 'aaa',
  },
  b: {
    label: 'bb',
    value: 'bbb',
  },
  c: {
    label: 'cc',
    value: 'ccc',
  },
  d: {
    label: 'dd',
    value: 'ddd',
  },
} as const;

// enforce assignment here
const BAR = 'aa'; // or 'bb'

Solution

  • Solution

    type FOO_TYPE = typeof FOO;
    
    /*
      FOO_TYPE would give the type of entire object:
    
      readonly a: {
        readonly label: "aa";
        readonly value: "aaa";
      };
      readonly b: {
        readonly label: "bb";
        readonly value: "bbb";
      };
      readonly c: {
        readonly label: "cc";
        readonly value: "ccc";
      };
    */
    
    // all the keys in FOO
    type FOO_KEYS = keyof FOO_TYPE; // "a" | "b" | "c" | "d"
    
    // all the keys except c and d
    type EXCLUDED_KEYS = Exclude<FOO_KEYS, 'c' | 'd'>; // "a" | "b"
    
    // enforce the assignment
    const BAR: FOO_TYPE[EXCLUDED_KEYS]['label'] = 'aa'; // "aa" | "bb"