vike-vue icon indicating copy to clipboard operation
vike-vue copied to clipboard

Improve DX of ClientOnly component

Open 4350pChris opened this issue 1 year ago • 3 comments

It'd be nice if we could have proper completion when using ClientOnly. E.g.

// Component.vue
<template>
  <p>{{ msg }}</p>
</template>
<script lang="ts" setup>
  defineProps<{ msg: string }>()
</script>

// App.vue
<template>
  <ClientOnly
    :load="() => import('./Component.vue')"
    msg="Hello World"
  />
</template>

Here we don't get a hint for msg even though it's passed to Component.vue.

4350pChris avatar Jan 11 '24 17:01 4350pChris

An easy workaround would be that we write the d.ts ourselves, instead of using the generated one.

brillout avatar Jan 11 '24 17:01 brillout

An easy workaround would be that we write the d.ts ourselves, instead of using the generated one.

Could you elaborate?

My thinking was doing something along these lines

ClientOnly.vue

<script lang="ts" setup generic="T">
  type Props = {
     load: T
  }

  type ForwardProps = Awaited<ReturnValue<T>>["props"] // this isn't correct, I don't know how to get the props of the loaded component as of now

  defineProps<Props & ForwardProps>()
</script>

The main problem here is that we have a dynamic import, so I don't think I can just use the return value here. I have yet to try this out though.

4350pChris avatar Jan 11 '24 17:01 4350pChris

I don't know much about Vue's TypeScript support but, in principle, if we manually create the .d.ts file for ClientOnly ourselfes then that should work (assuming SFC's TypeScript support is "lossless").

I guess the question boils down to that: can we make it work when the user doesn't use SFC? If yes and if SFC TypeScript is lossless, then we're good.

brillout avatar Jan 13 '24 11:01 brillout