vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.75k stars 8.35k forks source link

Union props #12449

Closed ZhangWillYu closed 1 day ago

ZhangWillYu commented 1 day ago

Vue version

3.5.13

Link to minimal reproduction

https://play.vuejs.org/#eNqNVk1z2zYQ/SsbHiy5Y4iKHTcZjqw09qTTdJqPSTK5lD1A5FJCBAIsAMpyXf33LkBKJGU7Ux1kYXexePv2YeH76E1VTTY1Rkk0s5kRlQOLrq5AcrW8SiNn02ieKlFW2jj4CbiFbzVCYXQJI9o3OvjuYYnuWtbmmmfrpdG1ym+kPfPWz36Bfgm7dutkEtdOyDiT3FpKklJAIRR+rJzQyo7vUwX0UbzEBEY3uiy1eqeq2o3OUrU79RvcXYXwyejKwpUHNQn+376+/+ONc0YsaocWTqDNFA56nYAll1rubcgNX0gk+0JrWlHanc+dEQZfUtiVNH8+EJazbg+VcgUN6ABiFr7n44Ct2W+ldh5cE/XFr2YtnEryDFda5mjo8PEpXM1ho0VO5w9SlDpH+Y1L4nyf5703zZo64F9QtZTz8T0Y/LsWBvMECi4tIaVoXkuXhAhoOGuSCvurzuo9bQaLWVv9fBz2htCiVpnvBWh142smjC32DtNk0yLzRwTqZnGjItIMLRyWVKhDWvmNs1xsml/+kwRWSWN/djb/GQhmfEr9PvI+ENmDoLbAodF/XsPIrniubxnfoOFLpL4b6gFbUD/W8asp5Nysk9Z4uxIO48sp6fM4EYmyDVJYO8Ml+3k6jS+G+/eui+Dyyu2n6ETV2f9Ko26x58cgcSg2CJowF5LAr0Seo9pjP4fFkumKZ8LdsZdToDOVFb53jFNb2oxtD0IfhL8pQzQbFtpKx3Xt7YPpA7plhZdUtWUXUN2x55NLcLh1DYmgaydJpoy4ENbflDx5tkd3ftkStDyQc0nknLe8hSyB9eOj/WX344gCjl2/LEgP5OtUHUT8IKzw3kGcM8Ma46DaA0sDtTYciYISPOtdypOT5pZPehf6Kdr4wmpJUwkkFo7ocbqi70LiFrLaWG1YpYVyaIAIKC3LMCyOu96jvX9Sr78BvYcV5iedPAAXyjyExVTl/yv7MPkerc8LuV+jEcuVYy9Dkc/jcypTc8eCFVhQqB8MjMog51H5FiVmjimtsBUWf6SfmRTZmo5s59OPuLiR2uJHytaHGjL/I1TGXk37+gumF9PpE0z1f8/i3oSLzui1pAFbiOXku9WKntQwMIk5XVZComkftzRK9qOUCJPU2t+DzcuxnQW0Z4XZ+hH7d7v1tjT6ZNCi2RAvB5/jhsZj43775UO4Kwcnibb2vfuB8zOG5hHGJuyaxivB7sUFtO/Cg0+vz1f7duuQZk1bVLhPFLkL8WlE/x/Qy/1k6R3ci8mLsI+ekGj3H0RFsrk=

Steps to reproduce

<script setup lang="ts">
import * as Vue from 'vue'
import { getBlurBackgroundCls, getRoundedCls } from '../util/class'

defineOptions({
    name: 'CommonInput',
})

type Props = /* @vue-ignore */ Vue.InputHTMLAttributes & {
    class?: string
    clearable?: boolean
}

const { class: className, clearable } = defineProps<Props>()

const slots = defineSlots<{
    placeholder?: () => void
}>()

const modelValue = defineModel<string | null>({ required: false, default: null })

const isFocus = Vue.ref<boolean>(false)

function onClear() {
    modelValue.value = null
}
</script>

<template>
    <div
        :class="[
            getRoundedCls(),
            getBlurBackgroundCls(),
            isFocus
                ? 'shadow-average border-black/80 dark:border-white/50'
                : 'border-neutral-600/30 dark:border-neutral-300/30',
            className,
        ]"
        class="relative overflow-hidden border-2 bg-opacity-70 transition-all"
    >
        <input
            v-model="modelValue"
            class="w-full px-3 py-1.5 text-black outline-0 disabled:!opacity-25 dark:bg-neutral-500/20 dark:text-white"
            type="text"
            @blur="isFocus = false"
            @focus="isFocus = true"
        />

        <div
            v-if="!modelValue && slots.placeholder"
            class="absolute left-0 top-0 flex cursor-pointer items-center overflow-hidden px-3 py-1.5"
        >
            <slot name="placeholder" />
        </div>

        <div
            v-if="clearable"
            className="absolute right-7 top-1/2 float-right -translate-y-1/2 cursor-pointer select-none text-base"
            @click="onClear"
        >
            <CloseOne className="text-zinc-800 dark:text-zinc-400" />
        </div>
    </div>
</template>

What is expected?

The defineProps can work

What is actually happening?

If don't add /** vue-ignore */ will throw error

Unresolvable type reference or unsupported built-in utility type

System Info

No response

Any additional comments?

No response

edison1105 commented 1 day ago

https://github.com/vuejs/core/blob/3634f7a4c1649ad2e7e969eb4512512868c61d01/packages/runtime-dom/src/jsx.ts#L255 https://github.com/vuejs/core/blob/3634f7a4c1649ad2e7e969eb4512512868c61d01/packages/runtime-dom/src/jsx.ts#L1387-L1391

InputHTMLAttributes extends HTMLAttributes HTMLAttributes extends EventHandlers EventHandlers has conditional types which are not supported.

This limitation has been resolved in 3.3. The latest version of Vue supports referencing imported and a limited set of complex types in the type parameter position. However, because the type to runtime conversion is still AST-based, some complex types that require actual type analysis, e.g. conditional types, are not supported. You can use conditional types for the type of a single prop, but not the entire props object.

see https://vuejs.org/api/sfc-script-setup.html#type-only-props-emit-declarations