title: How to extend a keyof type so that it includes modified versions of the keys, e.g. prefixed with '-'?
body: <p>For example, I'd like to add Typescript type safety to the vanilla Javascript <a href="https://stackoverflow.com/a/4760279/13815493">Sort array of objects by string property value</a> solution. It accepts as args keys of the object to be sorted, to determine which key to sort by. If the key is prefixed with <code>-</code>, the sort is reversed.</p>
  <p>How would I do type the arg to accept, for example, both <code>&quot;age&quot;</code> and <code>&quot;-age&quot;</code>?</p>
  <p>This is my attempt:</p>
  <pre><code>export function dynamicSortMultiple&lt;T extends object, U extends keyof T&gt;(
    props: Array&lt;U&gt;,
  ) {
    function dynamicSort(key: U) {
      let sortOrder = 1
      if (typeof key === 'string' &amp;&amp; key.startsWith('-')) {
        sortOrder = -1
      }
      return function (a: T, b: T) {
        const result = a[key] &lt; b[key] ? -1 : a[key] &gt; b[key] ? 1 : 0
  
        return result * sortOrder
      }
    }
  
    return function (obj1: T, obj2: T) {
      let i = 0
      let result = 0
      const numberOfProperties = props?.length
      while (result === 0 &amp;&amp; i &lt; numberOfProperties) {
        result = dynamicSort(props[i])(obj1, obj2)
        i++
      }
  
      return result
    }
  }
  
  export interface User {
    userId: string
    firstName: string
    lastName: string
    login: string
    password: string
    rank: number
    score: number
    age?: number
  }
  
  dynamicSortMultiple&lt;User, keyof User&gt;(['firstName', 'score', '-age'])
  
  </code></pre>
  <p><a href="https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBAMwK4DsDGMCWEVwCYCeKAhgLaZoDK0MAskgDZZgPAA8AKnKDMCngGc4EAEYArYBgA0cAKrcQvfkIDWwAhARwOAPgAUAWABQcOGCgQwAgFxwAglCjECbWTqnGAlHADex08joWDj4RGQU1LB6agS2st5+JqZwrPACNADyUHjAUHAAvHAAjP7JmFp6MARgwJpwMQX5hQDkAjBQmCgA5s1wAGR99eoAdG3EsAIA6pgwABZ6zQC0zZ4Jpclw6bBZOXmFiyVJpgC+63BQwDBIULiBGNi4esS2HDIiL2tHyWg4befAAkY8EKxAA2jEALpwNhwETg9RQgD8cAOcFsYMhcB0sPhBCRxTRcAADMYzqYLlcbv9AUw4AAqTaZbK5M6nJJs0oU663VD3EJ6URiIovGSCgBMH18Z1ScEwBWJ0su1KB8pJXx+KD+KCQpBEuQyCAAChYarBMAD5eZLAJEcNWN05mcAO6zTCsOB6C404FNYn9QZymHa3X6o0m3JYAGfDbkgEqwqEEjkKg0PRWqygzAQzwC8RFUXiMWeMmygDUpdZpK+XKpXqBpTZHKMoEgsFlKF4UAQxDQwDkAlyUqSSAHUAAknhbG0Ot1SghMFA2gA5MjAKftTpdUoMYjL1frmdbpIMCBdToHzelMC7gRO6CTzYb2dJJwoFS2YN6qClAQ-C4fnUv1KYgumAREAJDb8jCbRNwhTWB6CYTAWHYWRRxkGI6jQ3J9FBZp50XGAV1IYBmhkVo-1I8jFhA0jsyAA" rel="noreferrer">typescript playground</a></p>
  <p>On the last line I see the error</p>
  <pre><code>Type '&quot;-age&quot;' is not assignable to type 'keyof User'.
  </code></pre>
  <p>Is there an any way to extend <code>keyof User</code> properly so that values prefixed with '-' are still considered valid values for the type?</p>
  <p>I'll appreciate any solution even if you replace mine entirely.</p>