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)
|
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', () => {
|
describe('defineModel', () => {
|
||||||
// overload 1
|
// overload 1
|
||||||
const modelValueRequired = defineModel<boolean>({ required: true })
|
const modelValueRequired = defineModel<boolean>({ required: true })
|
||||||
|
@ -336,6 +360,78 @@ describe('useSlots', () => {
|
||||||
expectType<Slots>(slots)
|
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
|
// #6420
|
||||||
describe('toRefs w/ type declaration', () => {
|
describe('toRefs w/ type declaration', () => {
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
|
@ -44,7 +44,7 @@ export type SlotsType<T extends Record<string, any> = Record<string, any>> = {
|
||||||
export type StrictUnwrapSlotsType<
|
export type StrictUnwrapSlotsType<
|
||||||
S extends SlotsType,
|
S extends SlotsType,
|
||||||
T = NonNullable<S[typeof SlotSymbol]>
|
T = NonNullable<S[typeof SlotSymbol]>
|
||||||
> = [keyof S] extends [never] ? Slots : Readonly<T>
|
> = [keyof S] extends [never] ? Slots : Readonly<T> & T
|
||||||
|
|
||||||
export type UnwrapSlotsType<
|
export type UnwrapSlotsType<
|
||||||
S extends SlotsType,
|
S extends SlotsType,
|
||||||
|
|
Loading…
Reference in New Issue