Home > Net >  Why does typescript not recognise that the keys of a generic are of type string?
Why does typescript not recognise that the keys of a generic are of type string?

Time:12-12

Here's a contrived example to demonstrate the issue

function funcWithGeneric<T extends Record<string, any>>(propertyName: keyof T){
    propertyName.toUpperCase() 
    // ^ Errors with
    // Property 'toUpperCase' does not exist on type 'string | number | symbol'.
    // Property 'toUpperCase' does not exist on type 'number'.(2339)
}

I assumed that the Record<string part would be enough to tell Typescript that the propertyName will be of a string type but apparently not.

Why is this?

CodePudding user response:

While T does have to extend Record<string,any> it isn't limited to properties having only string as keys.

consider:

const test: Record<string, any> = {
  a:"test",
  [3]:"test"
}

this is a valid assignment, while keyof test essentially is string|number

Is there a reason why you have T as a generic while you don't use in the function definition?

what you can do is something like

function funcWithGeneric<T extends Record<K, any>, K extends string>(propertyName: K){
    propertyName.toUpperCase() 
}

funcWithGeneric("test")

funcWithGeneric(4)

Playground

  • Related