core
core copied to clipboard
feat: runtime-support for type unions in props
One of the last missing features regarding TypeScript support in Vue is the ability to use discriminated- and distributive union types in props with runtime validation. This PR aims to address these limitations and provides a more flexible way to define props.
Fixes
- https://github.com/vuejs/core/issues/11758
- https://github.com/vuejs/core/issues/8952
- https://github.com/vuejs/core/issues/9125
- https://github.com/vuejs/core/issues/12106
Implementation
Through compiling and validating the new internal prop option union
, we can skip validation for props that are not part of an active sub-union.
In the following example, a
and b
are in an active sub-union, c
and d
are not. Defining either a
or b
should trigger warnings for missing props for the other prop in the same sub-union.
defineProps<
| {
a: string
b: number
}
| {
c: string
d: number
}
>()
// Usage
<Comp a="foo" /> // Should trigger missing required prop warning only for `b`
Limitations
- [x] Requires https://github.com/vuejs/core/pull/12077 for union type-safety.
Supported patterns
This proposal currently supports the following patters:
Discriminated union example
const props = defineProps<
| {
tag: string
d1: number
}
| {
tag: string
d2: string
}
>()
// Union definition:
{
tag: [['d1'], ['d2']],
d1: ['tag'],
d2: ['tag']
}
// Usage:
<Comp tag="asdf" :d1="1" /> // Should not warn regarding missing `d2`
Distributive union example
defineProps<
| {
a: string
b: number
}
| {
c: string
d: number
}
>()
// Union definition:
{
a: ['b'],
b: ['a'],
c: ['d'],
d: ['c'],
}
// Usage
<Comp a="foo" /> // Should trigger missing required prop warning only for `b`
Mentions
Shoutout to @KazariEX for helping me navigating various intricacies of the prop type system.