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
[email protected], [email protected], [email protected]. This feels more like a native VueJS or TypeScript issue, rather than anything to do with Quasar
UserInterface for reference:
export default interface UserInterface {
id: number,
email: string,
name: string,
agent_id: string
}
Component:
<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 documentation https://v3.vuejs.org/guide/typescript-support.html#using-with-composition-api states:
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
Result:
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 | })
Notes:
adding a @ts-ignore
above the line in question does remove the error, but that's not solving the issue.
I've tried deleting node_modules and restarting everything to ensure its not a glitch
its running in a docker image
You define a prop named disabled in MyComponent. vue . ... and then add the component like this, passing in disabled . Note that :disabled="true" and just disabled mean the same thing in both cases - when props are defined or not.
Vue 3 does not require using the Composition API.
To pass in the properties of an object as props, we can use the v-bind without the argument. Then the properties of post will be passed into blog-post as prop values. The property names are the prop names.
It is not compulsory that you have to use Composition API in order to use Vue 3. It still supports Options API at its core. It is also possible to use both methods together in a single Vue component.
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:
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 } } } })
Anders Hejlsberg, lead architect of TypeScript, explains the issue in a GitHub comment:
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
.
Original answer:
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.
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) => { /*...*/ },
},
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With