element-plus/packages/utils/tests/prop.spec.ts

377 lines
9.9 KiB
TypeScript
Raw Normal View History

import { expectTypeOf } from 'expect-type'
2021-09-29 09:52:58 +08:00
import { buildProp, definePropType, mutable, keyOf, buildProps } from '../props'
import type { propKey } from '../props'
2021-09-23 20:06:07 +08:00
import type { PropType, ExtractPropTypes } 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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
it('Values and required', () => {
expectTypeOf(
buildProp({
values: ['a', 'b', 'c'],
required: true,
} as const)
).toEqualTypeOf<{
readonly type: PropType<'a' | 'b' | 'c'>
readonly required: true
2021-09-23 20:06:07 +08:00
readonly default?: undefined
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
2021-09-23 20:06:07 +08:00
readonly default?: undefined
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
}>()
})
it('Normal type', () => {
expectTypeOf(
buildProp({
type: String,
})
).toEqualTypeOf<{
readonly type: PropType<string>
readonly required: false
readonly default: undefined
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
2021-09-23 20:06:07 +08:00
readonly default?: undefined
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
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
[propKey]: true
}>()
})
2021-09-23 20:06:07 +08:00
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
}>()
})
})
2021-09-29 09:52:58 +08:00
describe('buildProps', () => {
it('test buildProps', () => {
const propsCommon = buildProps({
type: {
type: String,
default: 'hello',
},
} as const)
const props = buildProps({
...propsCommon,
key1: {
type: definePropType<'a' | 'b'>(String),
},
key2: {
values: [1, 2, 3, 4],
},
key3: {
values: [1, 2, 3, 4],
default: 2,
},
key4: {
values: keyOf({ a: 'a', b: 'b' }),
default: 'a',
},
key5: Boolean,
key6: String,
key7: null,
key8: Object,
key9: Date,
key10: Set,
key11: undefined,
// nested
key12: buildProp({
type: String,
} as const),
} as const)
expectTypeOf(props).toEqualTypeOf<{
readonly type: {
readonly type: PropType<string>
readonly required: false
readonly default: 'hello'
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
}
2021-09-29 09:52:58 +08:00
readonly key1: {
readonly type: PropType<'a' | 'b'>
readonly required: false
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
readonly default: undefined
2021-09-29 09:52:58 +08:00
}
readonly key2: {
readonly type: PropType<1 | 2 | 3 | 4>
readonly required: false
readonly default: undefined
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
}
readonly key3: {
readonly type: PropType<1 | 2 | 3 | 4>
readonly required: false
readonly default: 2
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
}
readonly key4: {
readonly type: PropType<'a' | 'b'>
readonly required: false
readonly default: 'a'
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
}
readonly key5: BooleanConstructor
readonly key6: StringConstructor
readonly key7: null
readonly key8: ObjectConstructor
readonly key9: DateConstructor
readonly key10: SetConstructor
readonly key11: undefined
readonly key12: {
readonly type: PropType<string>
readonly required: false
readonly default: undefined
readonly validator: ((val: unknown) => boolean) | undefined
[propKey]: true
2021-09-29 09:52:58 +08:00
}
}>()
})
})