title: Using enums for keys in an object in order to reuse in mutation
body: <p>What is the best way to store the keys of an object and their types so that the keys can be used as a value and not just a type?
  I would like to check an attribute string against the enum within a mutation function so the type of the value can be checked against the expected type.</p>
  <p>When using enums to declare keys and then name the enum's types, TS doesn't seems to be checking if a value is within an enum or not correctly.</p>
  <p><a href="https://codesandbox.io/s/typescript-mutation-enum-question-zp7bv8?file=/src/index.ts" rel="nofollow noreferrer">Example code sandbox</a></p>
  <pre><code>export enum CellKeyStrings {
    CHARACTER = &quot;character&quot;,
    PATH_TO_BOARD = &quot;pathToBoardId&quot;
  }
  export enum CellKeyBooleans {
    IS_PASSABLE = &quot;isPassable&quot;
  }
  export enum CellKeyReadOnly {
    ID = &quot;id&quot;
  }
  
  type PartialRecord&lt;K extends string, T&gt; = {
    [P in K]?: T;
  };
  
  type ReadOnlyRecord&lt;K extends string, T&gt; = {
    readonly [P in K]: T;
  };
  
  type CellStringProperties = PartialRecord&lt;CellKeyStrings, string&gt;;
  type CellBooleanProperties = PartialRecord&lt;CellKeyBooleans, boolean&gt;;
  type CellReadOnlyProperties = ReadOnlyRecord&lt;CellKeyReadOnly, string&gt;;
  
  export interface Cell
    extends CellStringProperties,
      CellBooleanProperties,
      CellReadOnlyProperties {}
  
  interface MutationFunctionProps {
    cellId: string;
    attribute: keyof Cell;
    value: string | boolean;
  }
  const cells: Cell[] = [{ id: &quot;A-1&quot; }];
  
  const mutationFunction = ({
    cellId,
    attribute,
    value
  }: MutationFunctionProps) =&gt; {
    const selectedCell = cells.find(({ id }) =&gt; id === cellId);
  
    if (!selectedCell) {
      throw Error(&quot;cannot find cell&quot;);
    }
  
    if (
      Object.keys(CellKeyBooleans).includes(attribute) &amp;&amp;
      !Object.keys(CellKeyReadOnly).includes(attribute)
    ) {
      if (typeof value !== &quot;boolean&quot;) {
        throw Error(&quot;incorrect value type for attribute&quot;);
      }
      selectedCell[attribute] = value;
    }
  };
  </code></pre>