Mauricio Loya
Mauricio Loya

Reputation: 293

How to set types to vue slot props Typescript

I'm trying to set types on my slot props to handle in a table component as you can see in the image

enter image description here

I also have been trying with

#body={item: UserItem}, but it is only rename the parametter. #body={<UserItem>item} and #body={item<UserItem>}, but it does not work

Upvotes: 20

Views: 19941

Answers (3)

Craig Harshbarger
Craig Harshbarger

Reputation: 2263

The slot scope is an object so you need to type the object itself like

<template #body="{ item }: { item: UserItem }" />

But if the Table component is your own component you could also use generic in combination with defineProps and defineSlots to automatically infer the type for item in your slot based on the values prop that is passed in.

<script setup lang="ts" generic="T">
const props = defineProps<{
  values: T[]
}>()

const slots = defineSlots<{
  body(props: { item: T }): void
}>()
</script>

Upvotes: 39

kiborgKiller
kiborgKiller

Reputation: 497

You can do it with defineSlots

example:

 // in yout template

 <slot name="body" :msg="msg"></slot>

// in your script

defineSlots<{
  body(props: { msg: string }): any
}>()

and with that you will have msg as a string type

Upvotes: 9

Nick Kadutskyi
Nick Kadutskyi

Reputation: 188

Creating element as a render function can help to resolve the issue because you won't need to deal with typescript inside Vue template. In render function you will be able to use types however you want.

Here is how your render function might look like:

<template>
  <div>
    <render />
  </div>
</template>
<script setup lang="ts">
import {h} from "vue";
import {Table} from "...";

interface UserItem {
  name: string;
  id: string;
};

const values = {};

const render = () => {
  return h(Table, {values: values, cols: ["Name", "id"]}, {
    body: ({item}: {item: UserItem}) => [
      h('th', item.name),
      h('th', item.id)
    ],
  });
};
</script>

P.S.

I haven't tested the code but I wrote similar code that worked in my case. See my another response related to this question: https://stackoverflow.com/a/75518154/5746474

Upvotes: 1

Related Questions