Subscribe on changes!

`SlotsType<{ default: T }>` does not type in `defineComponent` "Functional Signature" mode

avatar
Nov 21st 2023

Vue version

3.3.8

Link to minimal reproduction

https://play.vuejs.org/#eNrdVD1v2zAQ/SsHTjZgS2jTyVHstEEKtENTNN7CDIp0cZRSJEFSjgNB/71Hykok2Sk6dCjqReR9vXfHd67ZR62jbYVswRKbmUI7sOgqDSKVmzPOnOVsyWVRamUcXKhSXwvlru4eMXNwb1QJnEXx0O7rcXbKZaakHSetnzXmcDayJrIq79AsKekA7HMlM1coeQjXed4A7NxjyM7eA03itnlqlS4OSy1Sh3QDSI7xX5TWT+fd+xPOYCEK6+h2Q9dbum/nlsLJQEFhekA/Oi+grv0XmiYUHo0tVA4EeqDDHv4u7KA2xSdxr3E2o7ened4Xm+jRKkkCqX06ZxmlFwLNlfbJpA8CaME4S4VQT1+DzZkKZ509e8Ds5xH7o915G2ffDVo0W3rGF59LzQZd6768/oY7Or84S5VXgqJ/4/yBVonKc2zDPlUyJ9q9uMD2S1BbITdre7lzKG3XlCfqI5sQzxmJzE/urdZf6Z5EJyGPy4ameLgbvV07umU1XPsVvFDSUV8z8NnWP9IMcrwvZKChJEoHTbcU3QZwibtQhCLTSoRvP2MSJLCeLcMBQBulLXXRCmV9Cl5UdLi53fcNkLndYsAoqZseqaTusCgNmuUypE3hbK/Ayesx1Iq8Sm20z1lFk0AhIvwprFYgKyFChbrjdrNX9Iza9Ow4u4XUgsQtmj3N6XCFaertKOdlqkfqbR3DpwvD8xJ5cI4Q4zjLJaXlKIqtiSS6WOoyPqew2FTSFSXOc1We0ztHH+KcKPXNEdpyfmfUE+k5ohZyqtTTnC8SlG7mBmWOxivyz7BHaX38kWvAwcMf0WP/z/N/VeRq0haZLiCVz/+IOJtfT4qIIg==

Steps to reproduce

Define a component like this:

<script lang="ts">
import { SetupContext, SlotsType, defineComponent } from "vue";

export default defineComponent(
  <T,>(
    props: { msg: T; list: T[] },
    ctx: SetupContext<{}, SlotsType<{ default: T }>>,
  ) =>
    () =>
      ctx.slots.default?.(props.msg) ?? null,
  { props: ["msg", "list"] as never[] },
);
</script>

What is expected?

No errors, because SlotType<{ name: type }> is accepted syntax

What is actually happening?

No overload matches this call.
  Overload 1 of 5, '(setup: (props: { msg: T; list: T[]; }, ctx: { attrs: Data; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: (exposed?: Record<string, any>) => void; }) => RenderFunction | Promise<...>, options?: Pick<...> & { ...; }): <T>(props: { ...; } & {}) => any', gave the following error.
  Overload 2 of 5, '(setup: (props: unknown[], ctx: { attrs: Data; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: (exposed?: Record<string, any>) => void; }) => RenderFunction | Promise<...>, options?: Pick<...> & { ...; }): (props: unknown[] & {}) => any', gave the following error.ts(2769)
CompSlotObject.vue(7, 39): 'default' is declared here.
CompSlotObject.vue(5, 3): Did you mean to call this expression?
CompSlotObject.vue(5, 3): Did you mean to call this expression?

System Info

No response

Any additional comments?

Replacing SlotsType<{ default: T }> with SlotsType<{ default?(msg: T): any }> works.

BTW, even in fixed version type of slot props in App.vue is any. Is this a vuejs/core issue, or vuejs/language-tools?

avatar
Nov 21st 2023

Using the SlotsType Helper here in this makes not sense, and it's not what it's been documented to be used for.

https://vuejs.org/api/options-rendering.html#slots

The ctx.slots object is an object containing slot functions, so typecasting it to something else makes no sense. Annotate it as what it is - an object containing functions.