-
-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Description
Describe the bug
Firstly, apologies if it seems like this should be an issue in the Vue 3 repo. I can move it across if that's the case.
I am trying to create a reusable Vue 3 component with generically typed props.
Let's say I want a props interface that looks something like:
// ChildComponent.vue
interface MyProps<T> {
propOne: T
propTwo: () => Array<T>
}The goal of this is so that something like the below would fail:
// ParentComponent.vue
<template>
<!-- 5 is a number, but "foo" and "bar" are strings 👎 -->
<child-component
:prop-one="5"
:prop-two="() => ["foo", "bar"]"
/>
</templateUsing this example, and also running into this issue I came up with the following:
// ChildComponent.vue
<script setup lang="ts">
defineProps<MyChildProps<unknown>>()
</script>
<script lang="ts">
export interface MyChildProps<T> {
propOne: T
propTwo: () => Array<T>
}
</script>
<template>
<div>{{ propOne }}</div>
</template>// ChildComponentWithGenerics.vue
<script lang="ts">
import ChildComponent from './ChildComponent.vue'
import type { MyChildProps } from './ChildComponent.vue'
type ChildComponentWithGenerics = new <T>(props: MyChildProps<T>) => {
$props: MyChildProps<T>
}
export default ChildComponent as ChildComponentWithGenerics
</script>This successfully results in the following:
// ParentComponent.vue
<script setup lang="ts">
const getSomeStrings = () => ["foo", "bar"]
</script>
<template>
<!-- 5 is a number, but "foo" and "bar" are strings 👎 -->
<child-component
:prop-one="5"
:prop-two="getSomeStrings"
/>
<!-- this is fine! 👍 -->
<child-component
prop-one="vite rocks!"
:prop-two="getSomeStrings"
/>
</template>Great, all working fine. That is, until I try and access the props in ChildComponent.vue...
As soon as I add const props = to then do some logic with the props, I get an error.
// ChildComponent.vue
<script setup lang="ts">
// accessing the props here causes the error ❌
const props = defineProps<MyChildProps<unknown>>()
</script>
<script lang="ts">
export interface MyChildProps<T> {
propOne: T
propTwo: () => Array<T>
}
</script>
<template>
<div>{{ propOne }}</div>
</template>The error I get is the following:
[plugin:vite:vue] Transform failed with 1 error:
/Users/josephmaylor/Desktop/vite-project/src/components/ChildComponent.vue:18:41: ERROR: Unexpected ")"/Users/josephmaylor/Desktop/vite-project/src/components/ChildComponent.vue:18:41
Unexpected ")"
16 | expose();
17 |
18 | const props = __props as Props>()
| ^
19 |
20 |at failureErrorWithLog (/Users/josephmaylor/Desktop/vite-project/node_modules/.pnpm/esbuild@0.15.10/node_modules/esbuild/lib/main.js:1566:15)
at /Users/josephmaylor/Desktop/vite-project/node_modules/.pnpm/esbuild@0.15.10/node_modules/esbuild/lib/main.js:805:29
at responseCallbacks. (/Users/josephmaylor/Desktop/vite-project/node_modules/.pnpm/esbuild@0.15.10/node_modules/esbuild/lib/main.js:671:9)
at handleIncomingPacket (/Users/josephmaylor/Desktop/vite-project/node_modules/.pnpm/esbuild@0.15.10/node_modules/esbuild/lib/main.js:726:9)
at Socket.readFromStdout (/Users/josephmaylor/Desktop/vite-project/node_modules/.pnpm/esbuild@0.15.10/node_modules/esbuild/lib/main.js:647:7)
at Socket.emit (node:events:526:28)
at addChunk (node:internal/streams/readable:315:12)
at readableAddChunk (node:internal/streams/readable:289:9)
at Socket.Readable.push (node:internal/streams/readable:228:10)
at Pipe.onStreamRead (node:internal/stream_base_commons:190:23
Reproduction
https://github.com/joemaylor/type-generic-props-repro
System Info
System:
OS: macOS 12.6
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 25.54 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.14.2 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 8.5.0 - /usr/local/bin/npm
Browsers:
Chrome: 106.0.5249.91
Firefox: 105.0.1
Safari: 16.0
npmPackages:
@vitejs/plugin-vue: ^3.0.3 => 3.1.0
vite: ^3.0.9 => 3.1.4 Used Package Manager
pnpm
Logs
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.