将道具传递到设置时,VueJS 3 Composition API 和 TypeScript 类型问题:类型上不存在属性“用户" [英] VueJS 3 Composition API and TypeScript type issue when passing props into setup: Property 'user' does not exist on type
问题描述
我正在努力找出我做错了什么让 TypeScript 理解 props.user
是 UserInterface
类型,任何建议或指针都会很棒
I am struggling to work out what I am doing wrong to get TypeScript to understand that props.user
is of type UserInterface
, any advice or pointers would be amazing
vue@3.1.1、typescript@4.2.2、quasar@2.0.0-rc.3.这感觉更像是原生 VueJS 或 TypeScript 问题,而不是与 Quasar 有任何关系
vue@3.1.1, typescript@4.2.2, quasar@2.0.0-rc.3. This feels more like a native VueJS or TypeScript issue, rather than anything to do with Quasar
用户界面供参考:
export default interface UserInterface {
id: number,
email: string,
name: string,
agent_id: string
}
组件:
<template>
<q-avatar :color="color" :text-color="textColor" :size="size" :title="user.name" style="outline: 2px solid #ffffff">
{{ initials(user.name) }}
</q-avatar>
</template>
<script lang="ts">
import UserInterface from 'logic/interfaces/UserInterface'
import {computed, defineComponent, PropType} from 'vue'
const colors: Record<string, string> = {
A: 'blue',
K: 'black',
R: 'purple',
S: 'primary'
}
export default defineComponent({
name: 'UserIcon',
props: {
user: {
type: Object as PropType<UserInterface>,
required: true
},
size: {
type: String,
required: false,
default: 'lg',
validator: function (value: string) {
return ['xs', 'sm', 'md', 'lg', 'xl'].indexOf(value) !== -1
}
},
textColor: {
type: String,
required: false,
default: 'white'
}
},
setup (props) {
const initial = props.user.agent_id.charAt(0)
const color = computed(() => {
return colors[initial] || 'green'
})
return {
color,
initials (name: string) {
const names = name.split(' ')
let initials = names[0].charAt(0)
if (names.length > 1) {
initials += names[names.length - 1].charAt(0)
}
return initials
}
}
}
})
</script>
VueJS 3 文档 https://v3.vuejs.org/guide/typescript-support.html#using-with-composition-api 声明:
VueJS 3 documentation https://v3.vuejs.org/guide/typescript-support.html#using-with-composition-api states:
在 setup() 函数中,您不需要将类型传递给 props 参数,因为它会从 props 组件选项推断类型.
On setup() function, you don't need to pass a typing to props parameter as it will infer types from props component option.
但是,我不断收到并发症错误,我不确定我错过了什么
However, i keep getting a complication error, and i am not sure what i am missing
结果:
Failed to compile.
TS2339: Property 'user' does not exist on type 'Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; ... 15 more ...; includes?: ((searchElement: string, fromIndex?: number | undefined) => boolean) | un...'.
38 | },
39 | setup (props) {
> 40 | const initial = props.user.agent_id.charAt(0)
| ^^^^
41 | const color = computed(() => {
42 | return colors[initial] || 'green'
43 | })
注意事项:在相关行上方添加 @ts-ignore
确实消除了错误,但这并不能解决问题.
Notes:
adding a @ts-ignore
above the line in question does remove the error, but that's not solving the issue.
我已经尝试删除 node_modules 并重新启动所有内容以确保它不是故障
I've tried deleting node_modules and restarting everything to ensure its not a glitch
它在 docker 镜像中运行
its running in a docker image
推荐答案
对于 validator
和 default
在 prop
声明中,this
参数:
For validator
and default
in the prop
declarations, the Vue docs prescribe either (1) using an arrow function, or (2) provide an explicit this
parameter:
由于 TypeScript 中的设计限制,当涉及到函数的类型推断时表达式,您必须注意对象和数组的 validator
和 default
值:
WARNING
Because of a design limitation in TypeScript when it comes to type inference of function expressions, you have to be careful with
validator
anddefault
values for objects and arrays:
import { defineComponent, PropType } from 'vue'
interface Book {
title: string
year?: number
}
const Component = defineComponent({
props: {
bookA: {
type: Object as PropType<Book>,
// Make sure to use arrow functions
default: () => ({
title: 'Arrow Function Expression'
}),
validator: (book: Book) => !!book.title
},
bookB: {
type: Object as PropType<Book>,
// Or provide an explicit this parameter
default(this: void) {
return {
title: 'Function Expression'
}
},
validator(this: void, book: Book) {
return !!book.title
}
}
}
})
TypeScript 的首席架构师 Anders Hejlsberg 在 GitHub 评论中解释了这个问题:
Anders Hejlsberg, lead architect of TypeScript, explains the issue in a GitHub comment:
这是设计限制.类似于 #38872.没有参数的 [n] 箭头函数不是上下文敏感的,但是没有参数的函数表达式是上下文敏感的,因为隐含的 this
参数.任何上下文敏感的东西都被排除在类型推断的第一阶段,这是确定我们将用于上下文类型参数的类型的阶段.因此,在原始示例中,当 a
属性的值是箭头函数时,我们成功地对 A
进行推断,然后再将上下文类型分配给 ab
的参数.但是当值是一个函数表达式时,我们不做任何推断并且 a
参数被赋予类型 unknown
.
This is a design limitation. Similar to #38872. A[n] arrow function with no parameters is not context sensitive, but a function expression with no parameters is context sensitive because of the implicit
this
parameter. Anything that is context sensitive is excluded from the first phase of type inference, which is the phase that determines the types we'll use for contextually typed parameters. So, in the original example, when the value for thea
property is an arrow function, we succeed in making an inference forA
before we assign a contextual type to the a parameter ofb
. But when the value is a function expression, we make no inferences and thea
parameter is given typeunknown
.
原答案:
您的一个道具与PropOptions
的预期签名不匹配,这显然破坏了setup()
中props
参数的类型推断代码>.具体来说,TypeScript 没有看到 size.validator
的签名与 PropOptions.validator
出于某种原因.
One of your props doesn't match the expected signature of PropOptions
, which apparently breaks the type inference for the props
argument in setup()
. Specifically, TypeScript doesn't see that the signature of size.validator
matches up with the type of PropOptions.validator
for some reason.
有趣的是,如果将 validator
更改为箭头函数,props
的类型推断就会成功:
Interestingly, if you change validator
to an arrow function, the type inference for props
succeeds:
export default defineComponent({
props: {
size: {
type: String,
required: false,
default: 'lg',
//validator: function (value: string) { /*...*/ },
validator: (value: string) => { /*...*/ },
},
}
})
这篇关于将道具传递到设置时,VueJS 3 Composition API 和 TypeScript 类型问题:类型上不存在属性“用户"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!