Open some-user123 opened 1 year ago
Found this issue looking at https://ui.nuxt.com/forms/form#backend-validation
I would love to be able to d something like
const form = ref<UForm|undefined>(undefined)
import type { Form } from '@nuxt/ui/dist/runtime/types/form'
const form = ref<Form<any>>()
@some-user123
My point is that the type exists, but is not correct.
(form.value as any).submit()
works. form.value.submit()
causes a type error.
<UForm id="...">
works. But causes a type error if you enable vueCompilerOptions.strictTemplates
.
The types don't match the actual implementation.
I stumbled upon this thread while searching how to import types and getting errors with the explicit import mentioned above:
error TS2307: Cannot find module '@nuxt/ui/dist/runtime/types' or its corresponding type declarations.
I wanted to mention that the (new?) way is:
import type { Form } from '#ui/types'
@romhml Do you think all of these are fixed in v3
? ๐ค
I'm not @romhml but I can comment, that so far I didn't find a similar issue in v3 ๐ฅณ
However, it could be I've missed such an error as there are many other type errors (#2532 and #2536).
I just found one issue ๐คจ:
<UInput @input="onInput" />
works, but causes a type error
[vue-tsc] Object literal may only specify known properties, and 'onInput' does not exist in type 'NonNullable<{ readonly modelValue?: string | number | undefined; readonly id?: string | undefined; readonly name?: string | undefined; readonly type?: InputTypeHTMLAttribute | undefined; ... 22 more ...; readonly "onUpdate:modelValue"?: ((value: string | number) => any) | undefined; } & VNodeProps & AllowedComponent...'.
But still, v3 is a huge improvement and really makes me consider @nuxt/ui
again. ๐
Found another one:
<UInput type="submit" form="ref" />
works, but fails type check:
Object literal may only specify known properties, and 'form' does not exist in type 'Partial<{}> & Omit<{ readonly disabled?: boolean | undefined; readonly icon?: string | undefined; readonly variant?: "link" | "solid" | "outline" | "soft" | "subtle" | "ghost" | undefined; ... 36 more ...; readonly loadingIcon?: string | undefined; } & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>'.
I could not reproduce any type issues mentioned except for the Form component using the v3
branch and useTemplateRef
. I submitted a fix for the form component which types the $el
attribute in order to access the form
element attributes without typing errors.
@some-user123 Could you summarize what exactly doesn't work? I couldn't reproduce the last two examples you sent.
I'd like to close this if everything's fine ๐
I think, this should be a minimal reproduction: https://github.com/some-user123/nuxt-ui-issue731.
If you run npx nuxi typecheck
on it:
app.vue:2:12 - error TS2353: Object literal may only specify known properties, and 'onInput' does not exist in type 'NonNullable<{ readonly modelValue?: string | number | undefined; readonly id?: string | undefined; readonly name?: string | undefined; readonly type?: InputTypeHTMLAttribute | undefined; ... 22 more ...; readonly onBlur?: ((event: FocusEvent) => any) | undefined; } & VNodeProps & AllowedComponentProps & ComponentCus...'.
2 <UInput @input="() => console.log('hi')"></UInput>
~~~~~
app.vue:3:26 - error TS2353: Object literal may only specify known properties, and 'form' does not exist in type '{ readonly label?: string | undefined; readonly color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral" | undefined; readonly variant?: "link" | "solid" | ... 4 more ... | undefined; ... 36 more ...; readonly inactiveClass?: string | undefined; } & VNodeProps & AllowedComponentProps & ...'.
3 <UButton type="submit" form="ref">Hello</UButton>
~~~~
If you disable strictTemplates
in tsconfig.json
(which I would consider bad practice), you can avoid these type errors , but you also don't get any hints that these properties are available:
Nor do you get errors if you use these properties wrongly, e.g.
<UInput @input="123">Hello</UInput>
<UButton type="submit" :form="() => console.log('foo')" />
Does this help?
So this is related to strictTemplates
(nuxt/ui#2562) and we can close this?
No, these are separate issues. #2562 is that already the pure installation of @nuxt/ui (without using any component of it) causes type errors when strictTemplates
is enabled.
This issue is that @nuxt/ui components are not properly typed. More specifically some properties are missing, e.g. form
of UButton
and @input
of UInput
.
This problem manifests itself in different ways:
strictTemplates
is enabledstrictTemplates
is disabledThere are thousands of possible props on the <input>
element. There is no way we can type them all: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attributes
It's the same about events, what do you need the @input
for in the first place? Why not use v-model
or @update:model-value
or even @change
? ๐ค
There are thousands of possible props on the
<input>
element. There is no way we can type them all: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attributes
<input>
elements are properly typed as HTMLInputElement
. I don't think you need to re-invent the wheel. If UInput
accepts the same parameters, you can inherit those. Types are available in vue, e.g. InputHTMLAttributes
(https://github.com/vuejs/core/blob/76c43c6040518c93b41f60a28b224f967c007fdf/packages/runtime-dom/src/jsx.ts#L518). I don't think you should hardcode all of them...
what do you need the
@input
for in the first place? Why not usev-model
or@update:model-value
or even@change
? ๐ค
Both @change
and @update:model-value
have a different signature and don't provide the actual event as parameter like @input
does.
Of course there are always ways around it. Ultimately, I could build my own component that wraps <input>
, but that's the whole point of using a library, making live easier, not harder...
If I already have full type support on <input>
incl. error checks and IDE support, I'd hope to get the same (and some more) from <UInput>
.
In PrimeVue (as an example), I not only get the types right, but also the full description:
Description
Components are not properly typed:
form
property on<UInput>
works, but is not typedid
property on<UForm>
works, but is not typedsubmit
method onForm<...>
works, but is not typedautocomplete
property on<UInput>
works, but is not typedCf: #668 #634
Additional context
No response