英文:
Using Partial<Type> on a Vue3 reactive() object is acting strangely
问题
我在使用 TypeScript 的 Partial 类型与 Vue3 的响应式对象时遇到了奇怪的行为。
我有一个简单的类型表示用户,并且需要创建一个可能一开始不具备某些属性的用户,因此我使用了 Partial 实用类型:
type User = {
id: number
name: string
}
const user_1: Partial<User> = {
name: 'John'
}
// ✅ 这里一切都正常
显然,当我尝试在用户中添加其他内容时,它会抛出错误:
const user_1: Partial<User> = {
name: 'John',
alive: true
// ❌ 类型 '{ … }' 不能分配给类型 'Partial<User>' [...] 'alive' 在类型 'Partial<User>' 中不存在
}
这是我从普通 TypeScript 中所期望的,所以这里没有问题。
但是奇怪的行为出现在我尝试使用部分对象声明一个 Vue3 响应式对象时:
import { reactive } from 'vue'
const user_2: Partial<User> = reactive({
id: 42,
name: 'Gerald',
alive: true
})
在这里,TypeScript 对于一切似乎都很清晰,不会产生任何问题。
奇怪的是,当我在模板中使用 user_2.alive
时,错误如预期地显示出来:
<template>
<h1>{{ user_2.alive }}</h1>
<!-- ❌ 属性 'alive' 在类型 'Partial<User>' 上不存在 -->
</template>
那么,为什么我在声明响应式对象时看不到错误呢?
我是否忽略了重要的内容,或者这可能是 TS 与 reactive() 的实现中的错误吗?
注意:我还尝试使用默认的 setup() 声明,以防它是与
<script setup>
注释有关的 bug,但问题仍然存在。
英文:
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 <script setup> 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==
答案1
得分: 1
你可以向 reactive
传递一个类型参数,以指定它接受的参数必须是那种类型:
const user_2 = reactive<Partial<User>>({
id: 42,
name: 'Gerald',
alive: true, // 错误
});
否则,它将自动推断类型。由于赋值允许多余的属性(在这里,将函数调用的返回值赋给 user_2
),所以这种赋值是允许的。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论