Reputation: 1
I've tried to create conditional props for my <Button /> component using discriminated union types. I don't want to allow pass down props like to, hash, linkBehavior
when another prop called render-as
is set to "button"
(and allow it only if render-as="link"
).
I've also set up default value of renderAs
to button
using withDefaults()
.
Problem: When I try to set up props like to, hash, linkBehvaior and I intentionally omit to set up render-as
(because it has its default value). I expect that TS throws an error, because of incompatibility of props. And it doesn't. (If I set render-as
manually, then everything works perfectly.)
Is there any solution to fix this and still keep my default value renderAs: 'button'
? Thank you.
Button.vue
<script setup lang="ts">
export type ButtonCommonProps = {
priority: 'primary' | 'secondary'
size: 'large' | 'small'
// ...
}
type ButtonConditionalProps =
| {
renderAs: 'button'
to: never
hash: never
linkBehavior: never
}
| {
renderAs: 'link'
to?: string
hash?: string
linkBehavior?: '_self' | '_blank' | '_parent' | '_top'
}
type ButtonProps = ButtonCommonProps & ButtonConditionalProps
const props = withDefaults(defineProps<ButtonProps>(), {
renderAs: 'button',
to: undefined,
hash: undefined,
linkBehavior: undefined,
// ...
})
// rest of the component...
Another Vue file
<template>
<!-- Here I expect error and it really occurs -->
<Button priority="primary" size"small" render-as="button" to="https://example.com">
Some text
</Button>
<!-- Here I expect error as well and it won't occur -->
<Button priority="primary" size"small" to="https://example.com">
Some text
</Button>
</template>
Upvotes: 0
Views: 230