import type { CSSProperties, VNodeChild, PropType } from 'vue'; import type { VueTypeValidableDef, VueTypesInterface } from 'vue-types'; import type { RouteComponent, RouteRecordRaw } from 'vue-router'; import { createTypes } from 'vue-types'; type VueNode = VNodeChild | JSX.Element; const propTypes = createTypes({ func: undefined, bool: undefined, string: undefined, number: undefined, array: undefined, object: undefined, integer: undefined, }); // // propTypes.extend([ // { // name: 'looseBool', // getter: true, // type: Boolean, // default: undefined, // }, // { // name: 'style', // getter: true, // type: [String, Object], // default: undefined, // }, // { // name: 'VNodeChild', // getter: true, // type: undefined, // }, // ]); // // function withUndefined<T extends { default?: any }>(type: T): T { type.default = undefined; return type; } const PropTypes = propTypes as VueTypesInterface & { readonly looseBool: VueTypeValidableDef<boolean>; readonly style: VueTypeValidableDef<CSSProperties>; readonly VNodeChild: VueTypeValidableDef<VueNode>; }; // https://stackoverflow.com/questions/46176165/ways-to-get-string-literal-type-of-array-values-without-enum-overhead export const tuple = <T extends string[]>(...args: T) => args; export const tupleNum = <T extends number[]>(...args: T) => args; /** * https://stackoverflow.com/a/59187769 * Extract the type of an element of an array/tuple without performing indexing */ export type ElementOf<T> = T extends (infer E)[] ? E : T extends readonly (infer F)[] ? F : never; /** * https://github.com/Microsoft/TypeScript/issues/29729 */ export type LiteralUnion<T extends U, U> = T | (U & {}); type DefaultFactory<T> = (props: Data) => T | null | undefined; export interface PropOptions<T = any, D = T> { type?: PropType<T> | true | null; required?: boolean; default?: D | DefaultFactory<D> | null | undefined | object; validator?(value: unknown): boolean; } interface RouteMeta { title: string; // 标题 icon?: string; // 图标 requiresAuth?: boolean; hideChildren?: boolean; // 是否不显示孩子菜单 } declare type Lazy<T> = () => Promise<T>; interface NsRouteRecordRaw extends Omit<Omit<RouteRecordRaw, 'children'>, 'meta'> { name: string; meta: RouteMeta; component?: Lazy<RouteComponent>; children?: NsRouteRecordRaw[]; props?: Recordable; } export { VueNode, PropTypes, NsRouteRecordRaw, withUndefined };