Wrong expected props in Vue3 custom component (TS)

62 Views Asked by At

I defined union type ComponentProps inside my component which may match with LinkComponentProps or BlockComponentProps. So, as I understand, when i passing to the component :is="link" prop, typescript should show an error about missing url property, but i don't got it.

<template>
  <component
    :is="tag"
    class="rounded-[16px] border border-color-border-default bg-color-surface-white "
    :class="{'transition-all duration-300 hover:scale-[1.005] hover:shadow-[0_0_20px_-8px_var(--purple-500)]': useHoverEffect}"
    :to="url"
  >
    <slot name="default" />
  </component>
</template>

<script setup lang="ts">
interface BaseComponentProps {
  useHoverEffect?: boolean
}

interface LinkComponentProps extends BaseComponentProps {
  is: 'link'
  url: string
}

interface BlockComponentProps extends BaseComponentProps {
  is: 'section' | 'div'
}

type ComponentProps = LinkComponentProps | BlockComponentProps;

const props = defineProps<ComponentProps>()

const tag = computed(() => {
  return props.is === 'link'
    ? resolveComponent('NuxtLink')
    : props.is
})

const url = computed(() => {
  return isLinkType(props) ? props.url : undefined
})

function isLinkType(props: ComponentProps): props is LinkComponentProps {
  return 'url' in props
}
</script>

I expected that when i passed 'section' or 'div' string to the :is prop, all be ok, but when I pass 'link', TS should show me an error about absent required expected url property.

// ok
<Card :useHoverEffect="true" :is="'div'" />

// ok
<Card :useHoverEffect="true" :is="'link'" :url="'/#'" />

// not ok
<Card :useHoverEffect="true" :is="'link'" />
0

There are 0 best solutions below