I'm facing a weird behavior when using a TypeScript Partial type with a Vue3 reactive object.
I have a simple type representing a User, and need to create a user that may not have some properties at first, so I used a Partial utility type :
type User = {
id: number
name: string
}
const user_1: Partial<User> = {
name: 'John'
}
// ✅ Everything's fine here
Obviously when I try to put something else in that user, it throws an error :
const user_1: Partial<User> = {
name: 'John',
alive: true
// ❌ Type '{ … }' is not assignable to type 'Partial<User>' […] 'alive' does not exist in type 'Partial<User>'
}
This is what I expect from plain TypeScript so no problem here.
But the strange behavior occurs when I try to declare a Vue3 reactive object with that partial :
import { reactive } from 'vue'
const user_2: Partial<User> = reactive({
id: 42,
name: 'Gerald',
alive: true
})
Here everything seems to be clear for TypeScript which doesn't yield anything.
What's strange is when I use that user_2.alive
in the template, the error shows up as expected :
<template>
<h1>{{ user_2.alive }}</h1>
<!-- ❌ Property 'alive' does not exist on type 'Partial<User>' -->
</template>
So, why can't I see the error at the declaration of the reactive object ? Did I omit something important or could that be a bug in the implementation of TS with reactive()?
Note: I also tried using the default setup() declaration, in cas of it would be a bug with the annotation, but the problem still remains
I could also reproduce the bug on the Vue3 Playground interface here : https://play.vuejs.org/#eNp9UstOwzAQ/JWVLwUJpeJxCqESIIToASoeN19Muk1dHNuynVIU5d9ZO7QEqfTm3RnPzj5adm1ttm6Q5azwpZM2gBK6uuIseM7AY2jshGtZW+MCtOBQlEGuETpYOFPDiP6OLrnmOnxZhDePDq6g5RpAznPQTf2O7iSGWtSYgw9O6iolREVxT+C6ixKl0T6ANq4WKirlMBMuSKGKGE2GwhdnA9HR1Cz1qBdVZC6HhVAeSTU562W3zvcLb9GjfyrcoxNq/qdGcE0scUw1inE/O5oUBQFrq0RAigCK5emkbQdNZVERug6KMUEDytBglmoQ64dUjHei7IRWQy0tZJWtvNG0ueSZs9LUVip0TzZIapmzvJ9XxIRS5nOactF36iP9WWL5sSe/8puY42zmkPyskbMdFoSrMPTw3csjbui9A2szbxSxD4DP6I1qoseedtPoOdke8JLbh3RzdC2v/m4TUPttU/3gAbrE54xO8PZA6792z7Pz9I+2xrpvqPX/OQ==
You can pass a type parameter to reactive
to say that the argument it takes must be of that type:
const user_2 = reactive<Partial<User>>({
id: 42,
name: 'Gerald',
alive: true, // ERROR
});
Otherwise, it will be inferred automatically. Since excess properties are allowed in assignment (here, assigning returned value from function call to user_2
), the assignment is allowed.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments