mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
refactor: improve buildProp (#3592)
This commit is contained in:
@@ -64,6 +64,30 @@ export function buildProp<
|
||||
: D
|
||||
validator?: ((val: any) => val is C) | ((val: any) => boolean)
|
||||
} = {}) {
|
||||
const _validator =
|
||||
values || validator
|
||||
? (val: unknown) => {
|
||||
let valid = false
|
||||
let allowedValues: unknown[] = []
|
||||
|
||||
if (values) {
|
||||
allowedValues = [...values, defaultValue]
|
||||
valid ||= allowedValues.includes(val)
|
||||
}
|
||||
if (validator) valid ||= validator(val)
|
||||
|
||||
if (!valid && allowedValues.length > 0) {
|
||||
debugWarn(
|
||||
`Vue warn`,
|
||||
`Invalid prop: Expected one of (${allowedValues.join(
|
||||
', '
|
||||
)}), got value ${val}`
|
||||
)
|
||||
}
|
||||
return valid
|
||||
}
|
||||
: undefined
|
||||
|
||||
type HasDefaultValue = Exclude<D, undefined> extends never ? false : true
|
||||
type Type = PropType<
|
||||
| (T extends PropWrapper<unknown>
|
||||
@@ -76,42 +100,24 @@ export function buildProp<
|
||||
>
|
||||
|
||||
return {
|
||||
type: ((type as any)?.[wrapperKey] || type) as unknown as Type,
|
||||
required: !!required as R,
|
||||
|
||||
default: defaultValue as unknown as R extends true
|
||||
? never
|
||||
: HasDefaultValue extends true
|
||||
? Exclude<
|
||||
D extends Record<string, unknown> | Array<any> ? () => D : D,
|
||||
undefined
|
||||
>
|
||||
: undefined,
|
||||
|
||||
validator:
|
||||
values || validator
|
||||
? (val: unknown) => {
|
||||
let valid = false
|
||||
let allowedValues: unknown[] = []
|
||||
|
||||
if (values) {
|
||||
allowedValues = [...values, defaultValue]
|
||||
valid ||= allowedValues.includes(val)
|
||||
}
|
||||
if (validator) valid ||= validator(val)
|
||||
|
||||
if (!valid && allowedValues.length > 0) {
|
||||
debugWarn(
|
||||
`Vue warn`,
|
||||
`Invalid prop: Expected one of (${allowedValues.join(
|
||||
', '
|
||||
)}), got value ${val}`
|
||||
)
|
||||
}
|
||||
return valid
|
||||
}
|
||||
: undefined,
|
||||
} as const
|
||||
type: (type as any)?.[wrapperKey] || type,
|
||||
required: !!required,
|
||||
default: defaultValue,
|
||||
validator: _validator,
|
||||
} as unknown as {
|
||||
readonly type: Type
|
||||
readonly required: R
|
||||
readonly validator: typeof _validator
|
||||
} & (R extends true
|
||||
? { readonly default?: undefined }
|
||||
: {
|
||||
readonly default: HasDefaultValue extends true
|
||||
? Exclude<
|
||||
D extends Record<string, unknown> | Array<any> ? () => D : D,
|
||||
undefined
|
||||
>
|
||||
: undefined
|
||||
})
|
||||
}
|
||||
|
||||
export const definePropType = <T>(val: any) =>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { expectTypeOf } from 'expect-type'
|
||||
import { buildProp, definePropType, mutable, keyOf } from '../props'
|
||||
|
||||
import type { PropType } from 'vue'
|
||||
import type { PropType, ExtractPropTypes } from 'vue'
|
||||
|
||||
describe('buildProp', () => {
|
||||
it('Only type', () => {
|
||||
@@ -67,7 +67,7 @@ describe('buildProp', () => {
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<'a' | 'b' | 'c'>
|
||||
readonly required: true
|
||||
readonly default: never
|
||||
readonly default?: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
@@ -147,7 +147,7 @@ describe('buildProp', () => {
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<number | 'a' | 'b' | 'c'>
|
||||
readonly required: true
|
||||
readonly default: never
|
||||
readonly default?: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
@@ -197,7 +197,7 @@ describe('buildProp', () => {
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<string>
|
||||
readonly required: true
|
||||
readonly default: never
|
||||
readonly default?: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
@@ -243,4 +243,23 @@ describe('buildProp', () => {
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('extract', () => {
|
||||
const props = {
|
||||
key1: buildProp({
|
||||
type: String,
|
||||
required: true,
|
||||
}),
|
||||
key2: buildProp({
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
}),
|
||||
} as const
|
||||
type Extracted = ExtractPropTypes<typeof props>
|
||||
|
||||
expectTypeOf<Extracted>().toEqualTypeOf<{
|
||||
readonly key1: string
|
||||
readonly key2: string | number
|
||||
}>()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user