Using v-for on an object with key/value, the key is typed as number
Vue version
3.3.4
Link to minimal reproduction
Steps to reproduce
Use v-for on an object with value and key as iterators, like in https://vuejs.org/guide/essentials/list.html#v-for-with-an-object Then check the type of the key variable (number)
What is expected?
The key type should be string
What is actually happening?
The key type is number
System Info
No response
Any additional comments?
My guess is that it is typed as a number because v-for is usually used on an array, and in that case the second argument is the index. But v-for also supports iterating on an object and in that case it will be a string.
/**
* v-for object
*/
export function renderList<T>(
source: T,
renderItem: <K extends keyof T>(
value: T[K],
key: K,
index: number
) => VNodeChild
): VNodeChild[]
const testObject: { [k: string]: string } = { key1: 'value2', key2: 'value2' }
type k = keyof typeof testObject . the type K is string | number
maybe this is the problem
Thanks for your input, it seems like the types for v-for
are declared here:
https://github.com/vuejs/core/blob/3.2/packages/runtime-core/src/helpers/renderList.ts#L41
And we can see that the second argument key
gets the type K
which is K extends keyof T
(with T
the type of the v-for source).
So in my case keyof { [key: string]: string }
evaluates to string | number
.
This was introduced with Typescript 2.9: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#support-number-and-symbol-named-properties-with-keyof-and-mapped-types
The use of keyof
seems logical, however in practice using v-for on an object will always provide the key as a string, so maybe Vue should directly type the key as string?