DerYeger / yeger

Monorepo for @yeger/ NPM packages
MIT License
306 stars 23 forks source link

bug: wrong type item prop in the #default slot #296

Closed Yizack closed 1 month ago

Yizack commented 2 months ago

Affected Packages

Description

Hello! I don't know exactly when I started having this issue and I don't know if this is a bug or I'm missing something, the component works as expected but the item prop in the #default slot isn't passing the correct type on my VSCode using Nuxt

Screenshot 2024-06-22 144101

I noticed that if I create a component using the code from vue-masonry-wall/src/masonry-wall.vue the types work but using the package gives the unknown type so I'm not sure if it's related to the build or something else I'm not doing.

Thanks for the support!

Reproduction

https://github.com/Yizack/masonrywall-repro

Additional context

Preferences

DerYeger commented 2 months ago

Thanks for the report! I've checked the implementation again, because I can reproduce your issue. However, the generic type of the component is correctly assigned to the slot. I'm not sure how to fix it, or if it is a build-tool/language-server related issue.

defineSlots<{
  default?: (props: {
    item: T
    column: number
    row: number
    index: number
  }) => any
}>()
MartinX3 commented 2 months ago

Also vue-tsc errors out because the type of { item } becomes unknown. Which results into error TS2322: Type 'unknown' is not assignable to type 'Exampletype'.

It worked with 5.0.10 before but there the type was also unknown. Just it didn't cause an error. So I assume they made the lint rules more strict.

I workarounded it by using

<masonry-wall :column-width="280" :gap="16" :items="items[it]">
  <template #default="{ item }">
    <c-mycomponent :model-value="item as Exampletype" />
  </template>
</masonry-wall>
Yizack commented 2 months ago

Potentially related issue:

DerYeger commented 1 month ago

5.0.13 should fix the issue. I've adapted the documentation's code to catch similar issues in the future.

MartinX3 commented 1 month ago

@DerYeger Thank you but maybe that led to this new error

 Argument of type '{ columnWidth: number; gap: number; items: Gallery[] | undefined; }' is not assignable to parameter of type 'never'.
  > 19 |         <masonry-wall :column-width="280" :gap="16" :items="items[it]">
       |          ^^^^^^^^^^^^
DerYeger commented 1 month ago

Hmm, items: Gallery[] | undefined seems incorrect, as items is required to be defined.

MartinX3 commented 1 month ago

That also doesn't work

 ERROR(vue-tsc)  Argument of type '{ columnWidth: number; gap: number; items: Gallery[]; }' is not assignable to parameter of type 'never'.
  > 19 |         <masonry-wall v-if="items[it]" :column-width="280" :gap="16" :items="items[it]">
       |          ^^^^^^^^^^^^

or

 ERROR(vue-tsc)  Argument of type '{ columnWidth: number; gap: number; items: string[]; }' is not assignable to parameter of type 'never'.
DerYeger commented 1 month ago

Can you try importing MasonryWall in your SFC and using that instead of masonry-wall? If that doesn't work and typescript as well as vue-tsc are up-to-date I'd need a minimal reproduction to investigate. I have 2 projects using 5.0.13 and the error was fixed without the above issue.

MartinX3 commented 1 month ago

@DerYeger I tested around and found the reason.
The Quasar Framework now uses a stricter tslint option.

This is causing it: https://www.typescriptlang.org/tsconfig/#exactOptionalPropertyTypes

So masonry-wall probably needs a better type definition somewhere? Maybe it's never because a type definition is missing or maybe because using any? (any is anyway bad. See https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html)

DerYeger commented 1 month ago

I'm not using any here, the issue is https://github.com/vuejs/core/issues/6532#issuecomment-2271817365

MartinX3 commented 1 month ago

oh, I thought because of https://github.com/DerYeger/yeger/blob/8a14de0d3a9103600deb1c69e926c7adc8454cf4/packages/vue-masonry-wall/src/masonry-wall.vue#L49

In my comment in the vuejs/core issue my problem was that I couldn't omit entries in withDefaults. So I just set them variable: undefined there to fix this issue.

And I don't get the exactOptionalPropertyTypes: true error message in the error with this plugin.

DerYeger commented 1 month ago

See https://blog.vuejs.org/posts/vue-3-3#typed-slots-with-defineslots for the single any justification.

I'm using withDefaults, so exactOptionalPropertyTypes: true breaks the types for Vue.

MartinX3 commented 1 month ago

Oh, thank you!