title: How to declare property type based on value of some other property in TypeScript
body: <p>I have this:</p>
  
  <pre class="lang-js prettyprint-override"><code>export type FieldType = 'number' | 'boolean' | 'string';
  
  export interface IField {
    key: string;
    value: any;
    type: FieldType;
  }
  </code></pre>
  
  <p>Is it possible to replace <code>values</code>'s <code>any</code> type withe some other definition so that values that are stored in <code>value</code> property are actually of type that <code>type</code> field contains. I.e. if an object has <code>'string'</code> value in <code>type</code> property, values that <code>value</code> property holds must be of type <code>string</code> (and so for <code>number</code> and <code>boolean</code> also).</p>
  
  <p>So that this work this way:</p>
  
  <pre class="lang-js prettyprint-override"><code>const booleanTypeError = &lt;IField&gt;{
    key: 'someKey',
    value: 'true', // throw error
    type: 'boolean'
  };
  
  const booleanTypeOK = &lt;IField&gt;{
    key: 'someKey',
    value: true, // no error
    type: 'boolean'
  };
  
  const stringTypeOK = &lt;IField&gt;{
    key: 'someKey',
    value: 'true', // no error
    type: 'string'
  };
  
  const stringTypeError = &lt;IField&gt;{
    key: 'someKey',
    value: true, // throw error
    type: 'string'
  };
  </code></pre>
  
  <p>I tried to use <code>keyof</code> and <code>typeof</code>, but no luck as I was getting errors all the time. I'm using TypeScript 3.7.5 (but I can use 3.8 also).</p>