1

I have run into a problem with an interface with keys defined as strings. Its property cannot be passed to a function that accepts strings types. I have reduced it to the simplest case.

(playground link)

interface Props {
  [key: string]: any
}

function setPropInternal(prop : string, value : any) : void {}

function setProp<T extends keyof Props>(prop: T, value: Props[T]) : void {
  // Why does this throw an error if key is defined as a string? (line 2)
  // Error at prop:
  //  Argument of type 'T' is not assignable to parameter of type 'string'.
  //   Type 'string | number' is not assignable to type 'string'. 
  //    Type 'number' is not assignable to type 'string'.
  setPropInternal(prop, value);
}
Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
Maciej Krawczyk
  • 14,825
  • 5
  • 55
  • 67
  • interesting, `keyof Props` is `string | number` [demo](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgApQPYAcDOyDeAUMsgNoDWEAngFzI5hSgDmAunXCFYQL6FhUsKAILIAvMkpUMMNJlwBuIA) – Tadhg McDonald-Jensen Sep 26 '20 at 16:06
  • 1
    see here https://stackoverflow.com/a/51808262/6513723 or short explanation: indexing with numbers is internally converted to string in JavaScript, so using `keyof` on an object with a string index signature will always return `string | number`. – pascalpuetz Sep 26 '20 at 16:12
  • Thanks. For quick reference, this can be fixed with: ... updateProp(prop : T, value : Props[T]) { ... – Maciej Krawczyk Sep 26 '20 at 16:42

0 Answers0