veui
Version:
Baidu Enterprise UI for Vue.js.
97 lines (88 loc) • 2.9 kB
TypeScript
// vue ts 文件问题:
// 1. makeDefaultOptional 中的 Omit 导致 { foo: true, bar: number } | { foo: false, bar: string } 失效
// 2. 从 PropsOption 推导 PropType 很多都推导不出来?
import {
VNodeProps,
CreateComponentPublicInstance,
AllowedComponentProps,
ComponentCustomProps,
ComputedOptions,
MethodOptions,
EmitsOptions
} from '@vue/runtime-dom'
import { MultiMixin, Mix } from './mixins'
import { KeyType, NullableProp } from './utils'
type PublicProps = VNodeProps & AllowedComponentProps & ComponentCustomProps
/**
* 定义 veui 组件:
* new (...args: any[]): VeuiDefineInstance<...> ,然后导出时加上 PP
*/
export type VeuiDefineInstance<
Props = {},
Emit extends EmitsOptions = {},
Slots = {},
Mixin extends Array<Mix> | Mix = [],
Method extends MethodOptions = {},
Computed extends ComputedOptions = {},
MergedMixin = MultiMixin<Mixin>,
RealProps = NullableProp<Props & KeyType<MergedMixin, 'props'>>,
RealEmit = Emit & KeyType<MergedMixin, 'emits'>,
RealMethod = Method & KeyType<MergedMixin, 'methods'>
> = CreateComponentPublicInstance<
RealProps,
{},
{},
Computed,
RealMethod extends MethodOptions ? RealMethod : never,
{},
{},
RealEmit extends EmitsOptions ? RealEmit : never
> & {
$scopedSlots: Slots
}
type AsyncComponentForVca = (
resolve: (component: any) => void,
reject: () => void
) => void
export type VeuiDefineComponent<T> = T & PublicProps & AsyncComponentForVca // hack for vca's defineComponent
// 不写成 mixin,因为 mixin 无法在 new() => instance 中捕获泛型
export type SearchableProps<T = unknown> = {
match?: (
item: T,
keyword: string | undefined,
context: { ancestors: Array<T> }
) => boolean | Array<[number, number]>
filter?: (
item: T,
keyword: string | undefined,
context: { ancestors: Array<T>; offsets: Array<[number, number]> }
) => boolean
}
type BaseNormalizedItem<ChildrenKey extends string> =
| string
| ({
label?: string
value?: unknown
} & {
[K in ChildrenKey]?: Array<BaseNormalizedItem<K>> | null
})
// 不用 Omit/Pick ,因为内部访问 keyof,对于有 [x: string] 这种 key 的参数,直接就把更具体的 key 忽略了
export type Normalized<
ChildrenKey extends string,
T extends BaseNormalizedItem<ChildrenKey>,
Loose extends boolean = false,
Extra extends Record<any, unknown> = {}
> = T extends string
? { label: T; value: T } // string to object
: T extends BaseNormalizedItem<ChildrenKey>
? {
[K in keyof T]: K extends ChildrenKey // 递归下去
? Array<Normalized<K, T, Loose>> | null
: T[K]
} & (KeyType<T, 'label'> extends string
? {}
: { label: KeyType<T, 'value'> }) &
// eslint-disable-next-line no-unused-vars
(Loose extends true ? { [K in any]: unknown } : {}) &
Extra
: never