question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Error `TS2322` using Vue's dynamically named Slots

See original GitHub issue

What happens and why it is wrong

When assembling a project with dynamic slots, the following error appears: image

[!] (plugin rpt2) Error: C:/Users/p.marusov/Desktop/element-ui/src/components/ElTable/ElTable.vue?vue&type=script&setup=true&lang.ts(227,7): semantic error TS2322: Type 'Function' is not assignable to type 'Slot'.
  Type 'Function' provides no match for the signature '(...args: any[]): VNode<RendererNode, RendererElement, { [key: string]: any; }>[]'.

The problem arises specifically because of this code. In its absence, the assembly is successful:

      <template v-for="(_, slot) in $slots" :key="_" #[slot]="scope">
        <slot :name="slot" v-bind="scope || {}" />
      </template>

rollup.config.js

:
export default [
  {
    input: "src/index.ts",
    output: [
      {
        format: "esm",
        file: "dist/index.mjs",
        exports: "named",
      },
      {
        format: "cjs",
        file: "dist/index.js",
        exports: "named",
      },
    ],
    external: ["vue", "quasar"],
    plugins: [
      del({ targets: "dist" }),
      peerDepsExternal(),
      nodeResolve(),
      vue(),
      typescript2({
        clean: true,
        typescript: ttypescript,
        tsconfig: "tsconfig.rollup.json",
      }),
      babel({ babelHelpers: "runtime" }),
      commonjs(),
      postcss(),
      image(),
      terser(),
    ],
  },
];

tsconfig.json

:
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "declaration": true,
    "removeComments": true,
    "moduleResolution": "node",
    "isolatedModules": true,
    "noImplicitAny": false,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "plugins": [
      {
        "transform": "@zerollup/ts-transform-paths",
        "exclude": [
          "*"
        ]
      }
    ]
  },
  "files": [
    "src/index.ts",
    "src/shims-vue.d.ts"
  ],
  "exclude": ["node_modules"]
}

I tried to set the type of slots, but all to no avail.

 <template v-for="(_, slot) in ($slots as {})" :key="_" #[slot]="scope">
      <slot :name="slot" v-bind="scope || {}" />
    </template>

or

 <template v-for="(_, slot) in ($slots as Slots)" :key="_" #[slot]="scope">
      <slot :name="slot" v-bind="scope || {}" />
  </template>
<script lang="ts">
  import { Slots } from "vue";
</script>

I don’t understand how this can be fixed.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7

github_iconTop GitHub Comments

1reaction
tiagoskanetacommented, Oct 11, 2022

the issue I have is somewhat related. but it occurs when actually using a conditional template. I forked @agilgur5 repo here.

in essence, by doing:

<my-component>
    <template v-if="true" #foo> Bar </template>
  </my-component>

This is being transpiled to:

function render(_ctx, _cache, $props, $setup, $data, $options) {
  const _component_my_component = resolveComponent("my-component");

  return (openBlock(), createBlock(_component_my_component, null, createSlots({ _: 2 /* DYNAMIC */ }, [
    {
          name: "foo",
          fn: withCtx(() => [
            _hoisted_1
          ])
        }
      
  ]), 1024 /* DYNAMIC_SLOTS */))
}

Where I get the following error: image

Not really sure the issue is on rpt2 or on vue side, as it seems the transpiled/generated code doesn’t match the interface of createSlots in this case.

For the record, I can get away with it by declaring something like this:

// types/vue.d.ts
import 'vue'
declare module 'vue' {
  function createSlots(
    slots: Record<string, any>,
    dynamicSlots: (any | any[] | undefined)[]
  ): Record<string, any>
}

Which is fine for my case as I never call the createSlots function directly, so the loss of proper type checking on it is okay.

1reaction
Shenorcommented, May 16, 2022

vue-tsc did not give results. It doesn’t output anything about dynamic slots. Disabling verification check: false is the only solution so far, but not the one that I would like. Thank you for the answer, I will continue to understand

Read more comments on GitHub >

github_iconTop Results From Across the Web

vue Dynamic Slot Names Error Templates should only be ...
I am using Vuejs(2.6.11) Dynamic Slot Names Eerror: Templates should only be responsible for mapping the state to the UI.
Read more >
semantic error ts2322 | The AI Search Engine You Control
Semantic error TS2322 Type 'GridMaterial' is not assignable to type 'Material'. ... When assembling a project with dynamic slots, the following error ...
Read more >
Slots - Vue.js
In a parent component using <BaseLayout> , we need a way to pass multiple slot content fragments, each targeting a different slot outlet....
Read more >
Vue Components — Dynamic Slot Names and Shorthands
Since Vue.js 2.6.0, we can pass in dynamic slot names with v-slot . For example, we can use it as follows: In the...
Read more >
Vue.js Components — Slots and Dynamic Components
The text Error that we put between the error-box tags replace the slot tag, so we get the word 'Error' in red displayed....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found