Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using v-for on an object with key/value, the key is typed as number #8819

Closed
antoinematyja opened this issue Jul 20, 2023 · 2 comments · Fixed by #10963
Closed

Using v-for on an object with key/value, the key is typed as number #8819

antoinematyja opened this issue Jul 20, 2023 · 2 comments · Fixed by #10963

Comments

@antoinematyja
Copy link

Vue version

3.3.4

Link to minimal reproduction

https://play.vuejs.org/#eNp9UmFLwzAQ/StHELZB3XD7VraBygT94ET9ZoTV7la7pUlI0jop/e9eUrdVkPVDyb17effetTW71npYlchiNrWpybUDi67UIBKZzThzlrM5l6mS1oFD65YfW0xdDDW87WKwzuQyez8coIEZ1FwC7PD7KoZelYgSx73oFxqfIC4bLrvCd6VMXa4kKfQTk9HtVjMCquhiWw1gNm8nGLJpJKwuas9uYgiHcbMKytNRm4a8U+Gw0CJxSBXAdJ1XUF1ulKF8/WAn8uYGkMtORM4gJpQ49A5LAHrq+o/ZPvUiCBoDaGguyY9In9jTUWcqi2iTlHWTZ8OtVZLWHUJwlqpC5wLNUns92jatth3FWSKE+noImDPk8oCnn5ju/sG3du8xzp4MWjQVcnbsOVoOUijfXrw84p7Ox2ah1qUg9pnmM1olSu+xpd2Uck22O7zg9r7Qyjj6UK92sXco7SGUN+qZTeBzRv/c7ZnoJ7uT4STco8/Kmh/qs+TD

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.

@yangliguo7
Copy link

/**
 * 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

@antoinematyja
Copy link
Author

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?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants