From cb132248c6b8891fb4d0679acaf8730767c677e9 Mon Sep 17 00:00:00 2001 From: xingyu Date: Tue, 17 Oct 2023 11:10:43 +0800 Subject: [PATCH] fix: type --- .../VFormDesign/components/ComponentProps.vue | 14 ++- .../components/FormItemColumnProps.vue | 2 +- .../VFormDesign/components/FormItemProps.vue | 3 + src/components/Scrollbar/src/util.ts | 13 ++- .../SimpleMenu/src/components/Menu.vue | 19 ++-- .../SimpleMenu/src/components/SubMenuItem.vue | 2 +- src/components/Tree/src/types/tree.ts | 2 +- src/hooks/web/useMessage.tsx | 14 +-- .../header/components/notify/NoticeList.vue | 7 +- src/logics/mitt/routeChange.ts | 8 +- src/utils/mitt.ts | 96 ++++++++++++------- src/utils/types.ts | 23 +++++ 12 files changed, 134 insertions(+), 69 deletions(-) diff --git a/src/components/FormDesign/src/components/VFormDesign/components/ComponentProps.vue b/src/components/FormDesign/src/components/VFormDesign/components/ComponentProps.vue index 906b2b5..dda6ded 100644 --- a/src/components/FormDesign/src/components/VFormDesign/components/ComponentProps.vue +++ b/src/components/FormDesign/src/components/VFormDesign/components/ComponentProps.vue @@ -141,14 +141,18 @@ const linkOptions = computed(() => {
- +
diff --git a/src/components/FormDesign/src/components/VFormDesign/components/FormItemColumnProps.vue b/src/components/FormDesign/src/components/VFormDesign/components/FormItemColumnProps.vue index fc6bcda..ccfeb7a 100644 --- a/src/components/FormDesign/src/components/VFormDesign/components/FormItemColumnProps.vue +++ b/src/components/FormDesign/src/components/VFormDesign/components/FormItemColumnProps.vue @@ -25,7 +25,7 @@ function showProps(exclude: string[] | undefined) {
diff --git a/src/components/FormDesign/src/components/VFormDesign/components/FormItemProps.vue b/src/components/FormDesign/src/components/VFormDesign/components/FormItemProps.vue index 9c24cf6..9c6e92f 100644 --- a/src/components/FormDesign/src/components/VFormDesign/components/FormItemProps.vue +++ b/src/components/FormDesign/src/components/VFormDesign/components/FormItemProps.vue @@ -56,6 +56,7 @@ const controlPropsList = computed(() => { @@ -66,6 +67,7 @@ const controlPropsList = computed(() => { @@ -75,6 +77,7 @@ const controlPropsList = computed(() => { diff --git a/src/components/Scrollbar/src/util.ts b/src/components/Scrollbar/src/util.ts index 65d6d98..198cff7 100644 --- a/src/components/Scrollbar/src/util.ts +++ b/src/components/Scrollbar/src/util.ts @@ -1,4 +1,5 @@ import type { BarMap } from './types' +import type { MergeAll } from '@/utils/types' export const BAR_MAP: BarMap = { vertical: { @@ -39,8 +40,16 @@ function extend(to: T, _from: K): T & K { return Object.assign(to as any, _from) } -export function toObject(arr: Array): Recordable { - const res = {} +/** + * [ + * { name: 'zhangsan', age: 18 }, + * { sex: 'male', age: 20 } + * ] + * => + * { name: 'zhangsan', sex: 'male', age: 20 } + */ +export function toObject(arr: T): MergeAll { + const res = {} as MergeAll for (let i = 0; i < arr.length; i++) { if (arr[i]) extend(res, arr[i]) diff --git a/src/components/SimpleMenu/src/components/Menu.vue b/src/components/SimpleMenu/src/components/Menu.vue index 884437d..19ed4d4 100644 --- a/src/components/SimpleMenu/src/components/Menu.vue +++ b/src/components/SimpleMenu/src/components/Menu.vue @@ -4,7 +4,7 @@ import type { SubMenuProvider } from './types' import { createSimpleRootMenuContext } from './useSimpleMenuContext' import { useDesign } from '@/hooks/web/useDesign' import { propTypes } from '@/utils/propTypes' -import mitt from '@/utils/mitt' +import { mitt } from '@/utils/mitt' // eslint-disable-next-line vue/no-reserved-component-names defineOptions({ name: 'Menu' }) @@ -28,11 +28,18 @@ const props = defineProps({ }) const emit = defineEmits(['select', 'open-change']) -const rootMenuEmitter = mitt() +const rootMenuEmitter = mitt<{ + 'on-update-opened': (string | number)[] + 'on-menu-item-select': string | number + 'open-name-change': { + name: string + opened: boolean + } +}>() const instance = getCurrentInstance() const currentActiveName = ref('') -const openedNames = ref([]) +const openedNames = ref<(string | number)[]>([]) const { prefixCls } = useDesign('menu') @@ -77,14 +84,14 @@ function updateOpened() { rootMenuEmitter.emit('on-update-opened', openedNames.value) } -function addSubMenu(name: string) { +function addSubMenu(name: string | number) { if (openedNames.value.includes(name)) return openedNames.value.push(name) updateOpened() } -function removeSubMenu(name: string) { +function removeSubMenu(name: string | number) { openedNames.value = openedNames.value.filter(item => item !== name) updateOpened() } @@ -115,7 +122,7 @@ provide(`subMenu:${instance?.uid}`, { onMounted(() => { openedNames.value = !props.collapse ? [...props.openNames] : [] updateOpened() - rootMenuEmitter.on('on-menu-item-select', (name: string) => { + rootMenuEmitter.on('on-menu-item-select', (name: string | number) => { currentActiveName.value = name nextTick(() => { diff --git a/src/components/SimpleMenu/src/components/SubMenuItem.vue b/src/components/SimpleMenu/src/components/SubMenuItem.vue index 829b343..2e9891c 100644 --- a/src/components/SimpleMenu/src/components/SubMenuItem.vue +++ b/src/components/SimpleMenu/src/components/SubMenuItem.vue @@ -10,7 +10,7 @@ import { propTypes } from '@/utils/propTypes' import { CollapseTransition } from '@/components/Transition' import { Icon } from '@/components/Icon' import { isBoolean, isObject } from '@/utils/is' -import mitt from '@/utils/mitt' +import { mitt } from '@/utils/mitt' defineOptions({ name: 'SubMenu' }) diff --git a/src/components/Tree/src/types/tree.ts b/src/components/Tree/src/types/tree.ts index 2ce00ef..d6f8bb1 100644 --- a/src/components/Tree/src/types/tree.ts +++ b/src/components/Tree/src/types/tree.ts @@ -37,7 +37,7 @@ export const treeProps = buildProps({ }, renderIcon: { - type: Function as PropType<(params: Recordable) => string>, + type: Function as PropType<(...params: any[]) => string>, }, helpMessage: { diff --git a/src/hooks/web/useMessage.tsx b/src/hooks/web/useMessage.tsx index 0ce8cd9..6537343 100644 --- a/src/hooks/web/useMessage.tsx +++ b/src/hooks/web/useMessage.tsx @@ -1,4 +1,4 @@ -import type { ModalFunc, ModalFuncProps } from 'ant-design-vue/lib/modal/Modal' +import type { ModalFuncProps } from 'ant-design-vue/lib/modal/Modal' import { message as Message, Modal, notification } from 'ant-design-vue' import { CheckCircleFilled, CloseCircleFilled, InfoCircleFilled } from '@ant-design/icons-vue' @@ -26,14 +26,6 @@ export interface ModalOptionsEx extends Omit { } export type ModalOptionsPartial = Partial & Pick -interface ConfirmOptions { - info: ModalFunc - success: ModalFunc - error: ModalFunc - warn: ModalFunc - warning: ModalFunc -} - function getIcon(iconType: string) { if (iconType === 'warning') return @@ -55,7 +47,7 @@ function renderContent({ content }: Pick) { /** * @description: Create confirmation box */ -function createConfirm(options: ModalOptionsEx): ConfirmOptions { +function createConfirm(options: ModalOptionsEx) { const iconType = options.iconType || 'warning' Reflect.deleteProperty(options, 'iconType') const opt: ModalFuncProps = { @@ -64,7 +56,7 @@ function createConfirm(options: ModalOptionsEx): ConfirmOptions { ...options, content: renderContent(options), } - return Modal.confirm(opt) as unknown as ConfirmOptions + return Modal.confirm(opt) } function getBaseOptions() { diff --git a/src/layouts/default/header/components/notify/NoticeList.vue b/src/layouts/default/header/components/notify/NoticeList.vue index 5b4884d..024c98c 100644 --- a/src/layouts/default/header/components/notify/NoticeList.vue +++ b/src/layouts/default/header/components/notify/NoticeList.vue @@ -47,10 +47,13 @@ watch( const isTitleClickable = computed(() => !!props.onTitleClick) const getPagination = computed(() => { const { list, pageSize } = props - if (isNumber(pageSize) && pageSize > 0 && list && list.length > pageSize) { + // compatible line 104 + // if typeof pageSize is boolean, Number(true) && 5 = 5, Number(false) && 5 = 0 + const size = isNumber(pageSize) ? pageSize : Number(pageSize) && 5 + if (size > 0 && list && list.length > size) { return { total: list.length, - pageSize, + pageSize: size, // size: 'small', current: unref(current), onChange(page) { diff --git a/src/logics/mitt/routeChange.ts b/src/logics/mitt/routeChange.ts index 691856b..b1d25ed 100644 --- a/src/logics/mitt/routeChange.ts +++ b/src/logics/mitt/routeChange.ts @@ -3,13 +3,15 @@ */ import type { RouteLocationNormalized } from 'vue-router' -import mitt from '@/utils/mitt' +import { mitt } from '@/utils/mitt' import { getRawRoute } from '@/utils' -const emitter = mitt() - const key = Symbol('route-change') +const emitter = mitt<{ + [key]: RouteLocationNormalized +}>() + let lastChangeTab: RouteLocationNormalized export function setRouteChange(lastChangeRoute: RouteLocationNormalized) { diff --git a/src/utils/mitt.ts b/src/utils/mitt.ts index ba36be8..67d3e49 100644 --- a/src/utils/mitt.ts +++ b/src/utils/mitt.ts @@ -1,34 +1,38 @@ -/* eslint-disable array-callback-return */ /** * copy to https://github.com/developit/mitt * Expand clear method */ - export type EventType = string | symbol // An event handler can take an optional event argument // and should not return a value -export type Handler = (event?: T) => void -export type WildcardHandler = (type: EventType, event?: any) => void +export type Handler = (event: T) => void +export type WildcardHandler> = ( + type: keyof T, + event: T[keyof T], +) => void // An array of all currently registered event handlers for a type -export type EventHandlerList = Array -export type WildCardEventHandlerList = Array +export type EventHandlerList = Array> +export type WildCardEventHandlerList> = Array> // A map of event types and their corresponding event handlers. -export type EventHandlerMap = Map +export type EventHandlerMap> = Map< + keyof Events | '*', + EventHandlerList | WildCardEventHandlerList +> -export interface Emitter { - all: EventHandlerMap +export interface Emitter> { + all: EventHandlerMap - on(type: EventType, handler: Handler): void - on(type: '*', handler: WildcardHandler): void + on(type: Key, handler: Handler): void + on(type: '*', handler: WildcardHandler): void - off(type: EventType, handler: Handler): void - off(type: '*', handler: WildcardHandler): void + off(type: Key, handler?: Handler): void + off(type: '*', handler: WildcardHandler): void - emit(type: EventType, event?: T): void - emit(type: '*', event?: any): void + emit(type: Key, event: Events[Key]): void + emit(type: undefined extends Events[Key] ? Key : never): void clear(): void } @@ -37,7 +41,10 @@ export interface Emitter { * @name mitt * @returns {Mitt} */ -export default function mitt(all?: EventHandlerMap): Emitter { +export function mitt>( + all?: EventHandlerMap, +): Emitter { + type GenericEventHandler = Handler | WildcardHandler all = all || new Map() return { @@ -48,46 +55,61 @@ export default function mitt(all?: EventHandlerMap): Emitter { /** * Register an event handler for the given type. - * @param {string|symbol} type Type of event to listen for, or `"*"` for all events + * @param {string|symbol} type Type of event to listen for, or `'*'` for all events * @param {Function} handler Function to call in response to given event * @memberOf mitt */ - on(type: EventType, handler: Handler) { - const handlers = all?.get(type) - const added = handlers && handlers.push(handler) - if (!added) - all?.set(type, [handler]) + on(type: Key, handler: GenericEventHandler) { + const handlers: Array | undefined = all!.get(type) + if (handlers) + handlers.push(handler) + + else + all!.set(type, [handler] as EventHandlerList) }, /** * Remove an event handler for the given type. - * @param {string|symbol} type Type of event to unregister `handler` from, or `"*"` - * @param {Function} handler Handler function to remove + * If `handler` is omitted, all handlers of the given type are removed. + * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler) + * @param {Function} [handler] Handler function to remove * @memberOf mitt */ - off(type: EventType, handler: Handler) { - const handlers = all?.get(type) - if (handlers) - handlers.splice(handlers.indexOf(handler) >>> 0, 1) + off(type: Key, handler?: GenericEventHandler) { + const handlers: Array | undefined = all!.get(type) + if (handlers) { + if (handler) + handlers.splice(handlers.indexOf(handler) >>> 0, 1) + + else + all!.set(type, []) + } }, /** * Invoke all handlers for the given type. - * If present, `"*"` handlers are invoked after type-matched handlers. + * If present, `'*'` handlers are invoked after type-matched handlers. * - * Note: Manually firing "*" handlers is not supported. + * Note: Manually firing '*' handlers is not supported. * * @param {string|symbol} type The event type to invoke * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler * @memberOf mitt */ - emit(type: EventType, evt: T) { - ;((all?.get(type) || []) as EventHandlerList).slice().map((handler) => { - handler(evt) - }) - ;((all?.get('*') || [])).slice().map((handler) => { - handler(type, evt) - }) + emit(type: Key, evt?: Events[Key]) { + let handlers = all!.get(type) + if (handlers) { + (handlers as EventHandlerList).slice().forEach((handler) => { + handler(evt as Events[Key]) + }) + } + + handlers = all!.get('*') + if (handlers) { + (handlers as WildCardEventHandlerList).slice().forEach((handler) => { + handler(type, evt as Events[Key]) + }) + } }, /** diff --git a/src/utils/types.ts b/src/utils/types.ts index 1155a5c..1b6d6d7 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -39,3 +39,26 @@ export type ComponentSize = 'large' | 'medium' | 'small' | 'mini' export type StyleValue = string | CSSProperties | Array export type Mutable = { -readonly [P in keyof T]: T[P] } + +type Merge = { + [K in keyof O | keyof T]: K extends keyof T ? T[K] : K extends keyof O ? O[K] : never; +} + +/** + * T = [ + * { name: string; age: number; }, + * { sex: 'male' | 'female'; age: string } + * ] + * => + * MergeAll = { + * name: string; + * sex: 'male' | 'female'; + * age: string + * } + */ +export type MergeAll = T extends [ + infer F extends object, + ...infer Rest extends object[], +] + ? MergeAll> + : R