简体   繁体   中英

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

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM