Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript issue with importing type from vue #8756

Open
viet34tqc opened this issue Jul 11, 2023 · 3 comments
Open

Typescript issue with importing type from vue #8756

viet34tqc opened this issue Jul 11, 2023 · 3 comments

Comments

@viet34tqc
Copy link

viet34tqc commented Jul 11, 2023

Vue version

3.3.4

Link to minimal reproduction

https://github.com/tragid/vue-default-export-error

Steps to reproduce

I'm trying to build a Button component using Typescript and utilizing types of HTML element imported from Vue package. Here is the code:

import type { ButtonHTMLAttributes, LinkHTMLAttributes } from 'vue'
import type { RouterLinkProps } from 'vue-router'

type ButtonOrAnchorProps = BaseProps & ButtonHTMLAttributes & LinkHTMLAttributes
type ButtonAsRouterLink = BaseProps & RouterLinkProps & LinkHTMLAttributes
type ButtonProps = ButtonAsRouterLink | ButtonOrAnchorProps

const props = defineProps<ButtonProps>()

What is expected?

The type should be imported normally without any error.

What is actually happening?

Vue throws error:

[@vue/compiler-sfc] Unresolvable type reference or unsupported built-in utility type

It's kind of strange because I can still access the attributes from props variable like props.href but the app is not running.

What I tried is to create alternative types that extend ButtonHTMLAttributes and LinkHTMLAttributes, it's like:

import { type ButtonHTMLAttributes, type LinkHTMLAttributes } from 'vue'

export interface BtnHTMLAttr extends /* @vue-ignore */ ButtonHTMLAttributes {}

export interface LinkHTMLAttr extends /* @vue-ignore */ LinkHTMLAttributes {}

The import error is gone but the app is still not functioning properly. When I add a href prop to the component, seems like the component doesn't recognize href prop

System Info

No response

Any additional comments?

No response

@Shyam-Chen
Copy link
Contributor

#8522

@viet34tqc
Copy link
Author

Hi, thanks for your reply.

For some reasons, I cannot get the href props even if I pass it in parent component. Here is my code for Button component:

<script setup lang="ts">
import clsx from 'clsx'
import type { ButtonHTMLAttributes, LinkHTMLAttributes } from 'vue'

// Here is tailwind class for variants
const variants = {
  primary: 'bg-blue-600 text-white hover:bg-gray-50:text-blue-600',
  secondary: 'bg-gray-200 text-black-300 hover:bg-blue-600:text-white'
}

interface BaseProps {
  variant?: keyof typeof variants
}

interface ButtonAsButton
  extends /* @vue-ignore */ BaseProps,
    /* @vue-ignore */ ButtonHTMLAttributes {}
interface ButtonAsLink extends /* @vue-ignore */ BaseProps, /* @vue-ignore */ LinkHTMLAttributes {}
type ButtonProps = ButtonAsButton | ButtonAsLink

const props = withDefaults(defineProps<ButtonProps>(), {
  variant: 'primary'
})

// Here you can add style from tailwind, below is the demo
const className = clsx(
  'flex items-center justify-center px-4 py-2 rounded font-medium focus:outline-none',
  variants[props.variant],
  props.class
)

const newProps = { ...props }

newProps.class = className
let As = 'button'
if ('href' in newProps) {
  As = 'a'
}
if (As === 'button') {
  newProps['type'] = newProps.type ? newProps.type : 'button'
}
</script>
<template>
  <As v-bind="newProps"><slot></slot></As>
</template>

<style scoped></style>

And I pass the href prop like: <VButton href="dsadsad">fdss</VButton>

However, href isn't recognized. What is the problem?

@Shyam-Chen
Copy link
Contributor

Ah! I didn't look carefully, but currently, I have separated Button and Link into two separate components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants