mirror of https://github.com/vuejs/core.git
fix(types): support for generic keyof slots (#8374)
This commit is contained in:
parent
0d61b429ec
commit
213eba479c
|
@ -260,6 +260,30 @@ describe('defineSlots', () => {
|
|||
expectType<Slots>(slotsUntype)
|
||||
})
|
||||
|
||||
describe('defineSlots generic', <T extends Record<string, any>>() => {
|
||||
const props = defineProps<{
|
||||
item: T
|
||||
}>()
|
||||
|
||||
const slots = defineSlots<
|
||||
{
|
||||
[K in keyof T as `slot-${K & string}`]?: (props: { item: T }) => any
|
||||
} & {
|
||||
label?: (props: { item: T }) => any
|
||||
}
|
||||
>()
|
||||
|
||||
for (const key of Object.keys(props.item) as (keyof T & string)[]) {
|
||||
slots[`slot-${String(key)}`]?.({
|
||||
item: props.item
|
||||
})
|
||||
}
|
||||
slots.label?.({ item: props.item })
|
||||
|
||||
// @ts-expect-error calling wrong slot
|
||||
slots.foo({})
|
||||
})
|
||||
|
||||
describe('defineModel', () => {
|
||||
// overload 1
|
||||
const modelValueRequired = defineModel<boolean>({ required: true })
|
||||
|
@ -336,6 +360,78 @@ describe('useSlots', () => {
|
|||
expectType<Slots>(slots)
|
||||
})
|
||||
|
||||
describe('defineSlots generic', <T extends Record<string, any>>() => {
|
||||
const props = defineProps<{
|
||||
item: T
|
||||
}>()
|
||||
|
||||
const slots = defineSlots<
|
||||
{
|
||||
[K in keyof T as `slot-${K & string}`]?: (props: { item: T }) => any
|
||||
} & {
|
||||
label?: (props: { item: T }) => any
|
||||
}
|
||||
>()
|
||||
|
||||
// @ts-expect-error slots should be readonly
|
||||
slots.label = () => {}
|
||||
|
||||
// @ts-expect-error non existing slot
|
||||
slots['foo-asdas']?.({
|
||||
item: props.item
|
||||
})
|
||||
for (const key in props.item) {
|
||||
slots[`slot-${String(key)}`]?.({
|
||||
item: props.item
|
||||
})
|
||||
slots[`slot-${String(key as keyof T)}`]?.({
|
||||
item: props.item
|
||||
})
|
||||
}
|
||||
|
||||
for (const key of Object.keys(props.item) as (keyof T)[]) {
|
||||
slots[`slot-${String(key)}`]?.({
|
||||
item: props.item
|
||||
})
|
||||
}
|
||||
slots.label?.({ item: props.item })
|
||||
|
||||
// @ts-expect-error calling wrong slot
|
||||
slots.foo({})
|
||||
})
|
||||
|
||||
describe('defineSlots generic strict', <T extends {
|
||||
foo: 'foo'
|
||||
bar: 'bar'
|
||||
}>() => {
|
||||
const props = defineProps<{
|
||||
item: T
|
||||
}>()
|
||||
|
||||
const slots = defineSlots<
|
||||
{
|
||||
[K in keyof T as `slot-${K & string}`]?: (props: { item: T }) => any
|
||||
} & {
|
||||
label?: (props: { item: T }) => any
|
||||
}
|
||||
>()
|
||||
|
||||
// slot-bar/foo should be automatically inferred
|
||||
slots['slot-bar']?.({ item: props.item })
|
||||
slots['slot-foo']?.({ item: props.item })
|
||||
|
||||
slots.label?.({ item: props.item })
|
||||
|
||||
// @ts-expect-error not part of the extends
|
||||
slots['slot-RANDOM']?.({ item: props.item })
|
||||
|
||||
// @ts-expect-error slots should be readonly
|
||||
slots.label = () => {}
|
||||
|
||||
// @ts-expect-error calling wrong slot
|
||||
slots.foo({})
|
||||
})
|
||||
|
||||
// #6420
|
||||
describe('toRefs w/ type declaration', () => {
|
||||
const props = defineProps<{
|
||||
|
|
|
@ -44,7 +44,7 @@ export type SlotsType<T extends Record<string, any> = Record<string, any>> = {
|
|||
export type StrictUnwrapSlotsType<
|
||||
S extends SlotsType,
|
||||
T = NonNullable<S[typeof SlotSymbol]>
|
||||
> = [keyof S] extends [never] ? Slots : Readonly<T>
|
||||
> = [keyof S] extends [never] ? Slots : Readonly<T> & T
|
||||
|
||||
export type UnwrapSlotsType<
|
||||
S extends SlotsType,
|
||||
|
|
Loading…
Reference in New Issue