mirror of
https://github.com/element-plus/element-plus.git
synced 2024-11-27 02:01:15 +08:00
refactor: improve buildProp (#3558)
* refactor: improve buildProp * fix: fix key * fix: improve validator
This commit is contained in:
parent
35c90180d1
commit
46d69bd37f
@ -106,6 +106,7 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^7.0.0-beta.0",
|
||||
"esno": "^0.9.1",
|
||||
"expect-type": "^0.12.0",
|
||||
"fast-glob": "^3.2.7",
|
||||
"file-save": "^0.2.0",
|
||||
"gulp": "^4.0.2",
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { buildProp } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType } from '@element-plus/utils/props'
|
||||
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import type { ZIndexProperty } from 'csstype'
|
||||
|
||||
export const affixProps = {
|
||||
zIndex: buildProp<ZIndexProperty>({
|
||||
type: [Number, String],
|
||||
zIndex: buildProp({
|
||||
type: definePropType<ZIndexProperty>([Number, String]),
|
||||
default: 100,
|
||||
}),
|
||||
} as const),
|
||||
target: {
|
||||
type: String,
|
||||
default: '',
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { buildProp } from '@element-plus/utils/props'
|
||||
import type { CSSProperties, ExtractPropTypes } from 'vue'
|
||||
import { buildProp, definePropType } from '@element-plus/utils/props'
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import type { ObjectFitProperty } from 'csstype'
|
||||
|
||||
export const avatarProps = {
|
||||
size: buildProp({
|
||||
@ -22,8 +23,8 @@ export const avatarProps = {
|
||||
},
|
||||
alt: String,
|
||||
srcSet: String,
|
||||
fit: buildProp<CSSProperties['objectFit']>({
|
||||
type: String,
|
||||
fit: buildProp({
|
||||
type: definePropType<ObjectFitProperty>(String),
|
||||
default: 'cover',
|
||||
} as const),
|
||||
} as const
|
||||
|
@ -3,10 +3,10 @@ import { buildProp } from '@element-plus/utils/props'
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
|
||||
export const badgeProps = {
|
||||
value: buildProp<string | number>({
|
||||
value: buildProp({
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
}),
|
||||
} as const),
|
||||
max: {
|
||||
type: Number,
|
||||
default: 99,
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { buildProp } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType } from '@element-plus/utils/props'
|
||||
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import type { RouteLocationRaw } from 'vue-router'
|
||||
|
||||
export const breadcrumbItemProps = {
|
||||
to: buildProp<RouteLocationRaw>({
|
||||
type: [String, Object],
|
||||
to: buildProp({
|
||||
type: definePropType<RouteLocationRaw>([String, Object]),
|
||||
default: '',
|
||||
}),
|
||||
} as const),
|
||||
replace: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { buildProp } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType } from '@element-plus/utils/props'
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import type { StyleValue } from '@element-plus/utils/types'
|
||||
|
||||
@ -7,10 +7,10 @@ export const cardProps = {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
bodyStyle: buildProp<StyleValue>({
|
||||
type: [String, Object, Array],
|
||||
bodyStyle: buildProp({
|
||||
type: definePropType<StyleValue>([String, Object, Array]),
|
||||
default: '',
|
||||
}),
|
||||
} as const),
|
||||
shadow: {
|
||||
type: String,
|
||||
default: '',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { isValidWidthUnit } from '@element-plus/utils/validators'
|
||||
import { buildProp } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType } from '@element-plus/utils/props'
|
||||
import { UPDATE_MODEL_EVENT } from '@element-plus/utils/constants'
|
||||
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
@ -9,8 +9,8 @@ export const dialogProps = {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
beforeClose: buildProp<(...args: any[]) => void>({
|
||||
type: Function,
|
||||
beforeClose: buildProp({
|
||||
type: definePropType<(...args: any[]) => void>(Function),
|
||||
}),
|
||||
destroyOnClose: {
|
||||
type: Boolean,
|
||||
@ -68,7 +68,7 @@ export const dialogProps = {
|
||||
required: true,
|
||||
},
|
||||
modalClass: String,
|
||||
width: buildProp<string | number>({
|
||||
width: buildProp({
|
||||
type: [String, Number],
|
||||
validator: isValidWidthUnit,
|
||||
}),
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { buildProp } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType } from '@element-plus/utils/props'
|
||||
|
||||
import type { VNode, ExtractPropTypes } from 'vue'
|
||||
|
||||
@ -29,12 +29,12 @@ export const messageProps = {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
message: buildProp<string | VNode>({
|
||||
type: [String, Object],
|
||||
message: buildProp({
|
||||
type: definePropType<string | VNode>([String, Object]),
|
||||
default: '',
|
||||
}),
|
||||
onClose: buildProp<() => void>({
|
||||
type: Function,
|
||||
} as const),
|
||||
onClose: buildProp({
|
||||
type: definePropType<() => void>(Function),
|
||||
required: false,
|
||||
}),
|
||||
showClose: {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { buildProp } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType } from '@element-plus/utils/props'
|
||||
|
||||
import type { VNode, ExtractPropTypes } from 'vue'
|
||||
|
||||
@ -30,20 +30,20 @@ export const notificationProps = {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
message: buildProp<string | VNode>({
|
||||
type: [String, Object],
|
||||
message: buildProp({
|
||||
type: definePropType<string | VNode>([String, Object]),
|
||||
default: '',
|
||||
}),
|
||||
offset: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
onClick: buildProp<() => void>({
|
||||
type: Function,
|
||||
onClick: buildProp({
|
||||
type: definePropType<() => void>(Function),
|
||||
default: () => undefined,
|
||||
}),
|
||||
onClose: buildProp<() => void, boolean>({
|
||||
type: Function,
|
||||
onClose: buildProp({
|
||||
type: definePropType<() => void>(Function),
|
||||
required: true,
|
||||
}),
|
||||
position: buildProp({
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { createVNode, defineComponent, renderSlot, h } from 'vue'
|
||||
import { PatchFlags } from '@element-plus/utils/vnode'
|
||||
import { useSameTarget } from '@element-plus/hooks'
|
||||
import { buildProp } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType } from '@element-plus/utils/props'
|
||||
|
||||
import type { ExtractPropTypes, CSSProperties } from 'vue'
|
||||
import type { ZIndexProperty } from 'csstype'
|
||||
|
||||
export const overlayProps = {
|
||||
mask: {
|
||||
@ -14,11 +15,15 @@ export const overlayProps = {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
overlayClass: buildProp<string | string[] | Record<string, boolean>>({
|
||||
type: [String, Array, Object],
|
||||
overlayClass: buildProp({
|
||||
type: definePropType<string | string[] | Record<string, boolean>>([
|
||||
String,
|
||||
Array,
|
||||
Object,
|
||||
]),
|
||||
}),
|
||||
zIndex: buildProp<CSSProperties['zIndex']>({
|
||||
type: [String, Number],
|
||||
zIndex: buildProp({
|
||||
type: definePropType<ZIndexProperty>([String, Number]),
|
||||
}),
|
||||
} as const
|
||||
export type OverlayProps = ExtractPropTypes<typeof overlayProps>
|
||||
|
@ -22,20 +22,19 @@ import { defineComponent, watch, computed, ref } from 'vue'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
import { ElSelect, ElOption } from '@element-plus/components/select'
|
||||
import { useLocaleInject } from '@element-plus/hooks'
|
||||
import { buildProp, mutable } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType, mutable } from '@element-plus/utils/props'
|
||||
import { usePagination } from '../usePagination'
|
||||
|
||||
import type { Nullable } from '@element-plus/utils/types'
|
||||
|
||||
const defaultPageSizes = mutable([10, 20, 30, 40, 50, 100] as const)
|
||||
const paginationSizesProps = {
|
||||
pageSize: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
pageSizes: buildProp<number[], false, typeof defaultPageSizes>({
|
||||
type: Array,
|
||||
default: () => defaultPageSizes,
|
||||
pageSizes: buildProp({
|
||||
type: definePropType<number[]>(Array),
|
||||
default: () => mutable([10, 20, 30, 40, 50, 100] as const),
|
||||
} as const),
|
||||
popperClass: {
|
||||
type: String,
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
} from 'vue'
|
||||
import { useLocaleInject } from '@element-plus/hooks'
|
||||
import { debugWarn } from '@element-plus/utils/error'
|
||||
import { buildProp, mutable } from '@element-plus/utils/props'
|
||||
import { buildProp, definePropType, mutable } from '@element-plus/utils/props'
|
||||
import { elPaginationKey } from '@element-plus/tokens'
|
||||
|
||||
import Prev from './components/prev.vue'
|
||||
@ -38,8 +38,6 @@ type LayoutKey =
|
||||
| 'sizes'
|
||||
| 'slot'
|
||||
|
||||
const defaultPageSizes = mutable([10, 20, 30, 40, 50, 100] as const)
|
||||
|
||||
export const paginationProps = {
|
||||
total: Number,
|
||||
pageSize: Number,
|
||||
@ -66,9 +64,9 @@ export const paginationProps = {
|
||||
['prev', 'pager', 'next', 'jumper', '->', 'total'] as LayoutKey[]
|
||||
).join(', '),
|
||||
},
|
||||
pageSizes: buildProp<number[], false, typeof defaultPageSizes>({
|
||||
type: Array,
|
||||
default: () => defaultPageSizes,
|
||||
pageSizes: buildProp({
|
||||
type: definePropType<number[]>(Array),
|
||||
default: () => mutable([10, 20, 30, 40, 50, 100] as const),
|
||||
}),
|
||||
popperClass: {
|
||||
type: String,
|
||||
|
@ -1,5 +1,21 @@
|
||||
import { debugWarn } from './error'
|
||||
import type { ExtractPropTypes, PropType } from '@vue/runtime-core'
|
||||
import type { Mutable } from './types'
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
const wrapperKey = Symbol()
|
||||
export type PropWrapper<T> = { [wrapperKey]: T }
|
||||
|
||||
type ResolveProp<T> = ExtractPropTypes<{
|
||||
key: { type: T; required: true }
|
||||
}>['key']
|
||||
type ResolvePropType<T> = ResolveProp<T> extends { type: infer V }
|
||||
? V
|
||||
: ResolveProp<T>
|
||||
type ResolvePropTypeWithReadonly<T> = Readonly<T> extends Readonly<
|
||||
Array<infer A>
|
||||
>
|
||||
? ResolvePropType<A[]>
|
||||
: ResolvePropType<T>
|
||||
|
||||
/**
|
||||
* @description Build prop. It can better optimize prop types
|
||||
@ -22,9 +38,14 @@ import type { PropType } from 'vue'
|
||||
@link see more: https://github.com/element-plus/element-plus/pull/3341
|
||||
*/
|
||||
export function buildProp<
|
||||
T = any,
|
||||
T = never,
|
||||
D extends
|
||||
| (T extends PropWrapper<any>
|
||||
? T[typeof wrapperKey]
|
||||
: ResolvePropTypeWithReadonly<T>)
|
||||
| V = never,
|
||||
R extends boolean = false,
|
||||
D extends T = T,
|
||||
V = never,
|
||||
C = never
|
||||
>({
|
||||
values,
|
||||
@ -33,44 +54,72 @@ export function buildProp<
|
||||
type,
|
||||
validator,
|
||||
}: {
|
||||
values?: readonly T[]
|
||||
type?: T
|
||||
values?: readonly V[]
|
||||
required?: R
|
||||
default?: R extends true
|
||||
? never
|
||||
: D extends Record<string, unknown> | Array<any>
|
||||
? () => D
|
||||
: D
|
||||
type?: any
|
||||
validator?: ((val: any) => val is C) | ((val: any) => boolean)
|
||||
} = {}) {
|
||||
type DefaultType = typeof defaultValue
|
||||
type HasDefaultValue = Exclude<T, D> extends never ? false : true
|
||||
type HasDefaultValue = Exclude<D, undefined> extends never ? false : true
|
||||
type Type = PropType<
|
||||
| (T extends PropWrapper<unknown>
|
||||
? T[typeof wrapperKey]
|
||||
: [V] extends [never]
|
||||
? ResolvePropTypeWithReadonly<T>
|
||||
: never)
|
||||
| V
|
||||
| C
|
||||
>
|
||||
|
||||
return {
|
||||
type: type as PropType<T | C>,
|
||||
type: ((type as any)?.[wrapperKey] || type) as unknown as Type,
|
||||
required: !!required as R,
|
||||
|
||||
default: defaultValue as R extends true
|
||||
default: defaultValue as unknown as R extends true
|
||||
? never
|
||||
: HasDefaultValue extends true
|
||||
? Exclude<DefaultType, undefined>
|
||||
? Exclude<
|
||||
D extends Record<string, unknown> | Array<any> ? () => D : D,
|
||||
undefined
|
||||
>
|
||||
: undefined,
|
||||
|
||||
validator:
|
||||
values || validator
|
||||
? (val: unknown) => {
|
||||
let valid = false
|
||||
if (values)
|
||||
valid ||= ([...values, defaultValue] as unknown[]).includes(val)
|
||||
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
|
||||
}
|
||||
|
||||
export const definePropType = <T>(val: any) =>
|
||||
({ [wrapperKey]: val } as PropWrapper<T>)
|
||||
|
||||
export const keyOf = <T>(arr: T) => Object.keys(arr) as Array<keyof T>
|
||||
export const mutable = <T extends readonly any[]>(val: T) =>
|
||||
val as Mutable<typeof val>
|
||||
export const mutable = <T extends readonly any[] | Record<string, unknown>>(
|
||||
val: T
|
||||
) => val as Mutable<typeof val>
|
||||
|
||||
export const componentSize = ['large', 'medium', 'small', 'mini'] as const
|
||||
|
246
packages/utils/tests/prop.spec.ts
Normal file
246
packages/utils/tests/prop.spec.ts
Normal file
@ -0,0 +1,246 @@
|
||||
import { expectTypeOf } from 'expect-type'
|
||||
import { buildProp, definePropType, mutable, keyOf } from '../props'
|
||||
|
||||
import type { PropType } from 'vue'
|
||||
|
||||
describe('buildProp', () => {
|
||||
it('Only type', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: definePropType<'a' | 'b'>(String),
|
||||
})
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<'a' | 'b'>
|
||||
readonly required: false
|
||||
readonly default: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Only values', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
values: [1, 2, 3, 4],
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<1 | 2 | 3 | 4>
|
||||
readonly required: false
|
||||
readonly default: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Type and values', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: definePropType<number[]>(Array),
|
||||
values: [1, 2, 3, 4],
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<1 | 2 | 3 | 4 | number[]>
|
||||
readonly required: false
|
||||
readonly default: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Values and validator', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
values: ['a', 'b', 'c'],
|
||||
validator: (val: unknown): val is number => typeof val === 'number',
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<number | 'a' | 'b' | 'c'>
|
||||
readonly required: false
|
||||
readonly default: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Values and required', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
values: ['a', 'b', 'c'],
|
||||
required: true,
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<'a' | 'b' | 'c'>
|
||||
readonly required: true
|
||||
readonly default: never
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Value and default', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
values: ['a', 'b', 'c'],
|
||||
required: false,
|
||||
default: 'b',
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<'a' | 'b' | 'c'>
|
||||
readonly required: false
|
||||
readonly default: 'b'
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Type and Array default value', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: definePropType<string[]>(Array),
|
||||
default: () => mutable(['a', 'b'] as const),
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<string[]>
|
||||
readonly required: false
|
||||
readonly default: () => ['a', 'b']
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Type and Object default value', () => {
|
||||
interface Options {
|
||||
key: string
|
||||
}
|
||||
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: definePropType<Options>(Object),
|
||||
default: () => mutable({ key: 'value' } as const),
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<Options>
|
||||
readonly required: false
|
||||
readonly default: () => { key: 'value' }
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Type, validator and Object default value', () => {
|
||||
interface Options {
|
||||
key: string
|
||||
}
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: definePropType<Options>(Object),
|
||||
default: () => ({ key: 'value' }),
|
||||
validator: (val: unknown): val is string => true,
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<string | Options>
|
||||
readonly required: false
|
||||
readonly default: () => { key: string }
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Type, validator, required', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: definePropType<'a' | 'b' | 'c'>(String),
|
||||
required: true,
|
||||
validator: (val: unknown): val is number => true,
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<number | 'a' | 'b' | 'c'>
|
||||
readonly required: true
|
||||
readonly default: never
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Normal type', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: String,
|
||||
})
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<string>
|
||||
readonly required: false
|
||||
readonly default: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Normal types', () => {
|
||||
expectTypeOf(buildProp({ type: [String, Number, Boolean] })).toEqualTypeOf<{
|
||||
readonly type: PropType<string | number | boolean>
|
||||
readonly required: false
|
||||
readonly default: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Normal type and values', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: String,
|
||||
values: ['1', '2', '3'],
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<'1' | '2' | '3'>
|
||||
readonly required: false
|
||||
readonly default: undefined
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Required and validator', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
required: true,
|
||||
validator: (val: unknown): val is string => true,
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<string>
|
||||
readonly required: true
|
||||
readonly default: never
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Required and validator', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
values: keyOf({ a: 'a', b: 'b' }),
|
||||
default: 'a',
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<'a' | 'b'>
|
||||
readonly required: false
|
||||
readonly default: 'a'
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Type and default value', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: definePropType<{ key: 'a' | 'b' | 'c' } | undefined>(Object),
|
||||
default: () => mutable({ key: 'a' } as const),
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<{ key: 'a' | 'b' | 'c' } | undefined>
|
||||
readonly required: false
|
||||
readonly default: () => { key: 'a' }
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
|
||||
it('Type and default value', () => {
|
||||
expectTypeOf(
|
||||
buildProp({
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
} as const)
|
||||
).toEqualTypeOf<{
|
||||
readonly type: PropType<string | number>
|
||||
readonly required: false
|
||||
readonly default: ''
|
||||
readonly validator: ((val: unknown) => boolean) | undefined
|
||||
}>()
|
||||
})
|
||||
})
|
@ -6219,6 +6219,11 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2:
|
||||
dependencies:
|
||||
homedir-polyfill "^1.0.1"
|
||||
|
||||
expect-type@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-0.12.0.tgz#133534b5e2561158c371e74af63fd8f18a9f3d42"
|
||||
integrity sha512-IHwziEOjpjXqxQhtOAD5zMiQpGztaEKM4Q8wnwoRN9NIFlnyNHNjRxKWv+18UqRfsqi6vVnZIYFU16ePf+HaqA==
|
||||
|
||||
expect@^26.6.2:
|
||||
version "26.6.2"
|
||||
resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417"
|
||||
|
Loading…
Reference in New Issue
Block a user