2.5.17
https://github.com/nel215/vue-sandbox
$ git clone https://github.com/nel215/vue-sandbox.git
$ cd vue-sandbox
$ yarn
$ ./node_modules/.bin/tsc index.ts
index.ts:5:9 - error TS2345: Argument of type '{}' is not assignable to parameter of type '"a"[]'.
Property 'length' is missing in type '{}'.
5 Vue.set(data.obj, 1, 'a')
~~~~~~~~
index.ts:6:12 - error TS2345: Argument of type '{}' is not assignable to parameter of type '{}[]'.
Property 'length' is missing in type '{}'.
6 Vue.delete(data.obj, 1)
Type checks by typescript succeed on this case.
Type checks by typescript fail on this case.
Can we use number as key of object on Vue.set/delete? If it's yes, I will create a PR which fixes types/vue.d.ts.
Shouldn't it be Vue.set(data.obj, '1', 'a') if data.obj is an object?
Using number as key of Object is not recommended? In my actual case of Vue.set(data.objects, obj.id, obj), obj.id is identifier and the type is number. So, I'd appreciate if we can use number with Object.
I'm not sure that allowing such implicit type conversion in typings. I think it's enough to convert the id to string by using String constructor or toString.
In js, the conversion is implicit but if you want to use strict typing, then you should cast your number into a string. Doing a[1] or a['1']` in js will implicitly access the same thing. That being said, typescript allows it without warning, so I think we should support it too
const a: Record<string, boolean> = {}
a['1'] = false
a[2] = true
Note that the inverse is not true for arrays:
const a: Record<string, boolean> = {}
a['1'] = false
a[2] = true
const b: boolean[] = []
b['1'] = false // Element implicitly has an 'any' type because index expression is not of type 'number'
b[2] = true
Could also go with fully strict instead, but that might annoy a few people
declare function set<T extends O[K], K extends keyof O, O>(object: O, key: K, value: T): T
const c: Record<string, boolean> = {}
const d: boolean[] = []
const e: { foo: 'bar' | 'baz' } = { foo: 'bar' }
set(c, '1', false)
set(c, 2, false) // nope
set(c, '3', 'a string') // nope
set(d, '1', false) // nope
set(d, 2, false)
set(d, 3, 'a string') // nope
set(e, '1', false) // nope
set(e, 2, false) // nope
set(e, 'foo', 'a string') // nope
set(e, 'bar', 'baz') // nope
set(e, 'foo', 'baz')
Thank you for your comments.
I did not fully understand the behavior of Object. I also agree that it is better to use String constructor, since access to Object using number is implicit. I will use string in my project as well.
Is it OK to close this issue?
no, don't close it, we may add support for it
OK.
Closed via #8709
Most helpful comment
In js, the conversion is implicit but if you want to use strict typing, then you should cast your number into a string. Doing
a[1]or a['1']` in js will implicitly access the same thing. That being said, typescript allows it without warning, so I think we should support it too