From 1fc63c59dd0f87c0026ff2014366b161d1c439fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E8=B6=85?= Date: Mon, 13 Jan 2025 18:12:59 +0800 Subject: [PATCH 1/3] wip: improve(ui): improve generated types --- packages/ui/package.json | 3 +- packages/ui/src/DateRanger/index.ts | 73 ++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/packages/ui/package.json b/packages/ui/package.json index 50b95c444..5b5e592c2 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -65,7 +65,8 @@ }, "devDependencies": { "@ant-design/pro-form": "^2.31.3", - "@ant-design/pro-layout": "^7.22.0" + "@ant-design/pro-layout": "^7.22.0", + "@types/hoist-non-react-statics": "^3.3.6" }, "peerDependencies": { "react": ">=16.9.0", diff --git a/packages/ui/src/DateRanger/index.ts b/packages/ui/src/DateRanger/index.ts index e74d74d8d..5c281df02 100644 --- a/packages/ui/src/DateRanger/index.ts +++ b/packages/ui/src/DateRanger/index.ts @@ -25,28 +25,55 @@ import InternalDateRanger from './Ranger'; export * from './Ranger'; -const DateRanger = Object.assign(InternalDateRanger, { - NEAR_1_MINUTES, - NEAR_5_MINUTES, - NEAR_10_MINUTES, - NEAR_20_MINUTES, - NEAR_30_MINUTES, - NEAR_1_HOURS, - NEAR_2_HOURS, - NEAR_3_HOURS, - NEAR_6_HOURS, - NEAR_12_HOURS, - TODAY, - LAST_1_DAY, - LAST_3_DAYS, - YESTERDAY, - THIS_WEEK, - LAST_WEEK, - THIS_MONTH, - LAST_MONTH, - THIS_YEAR, - LAST_YEAR, - NEXT_YEAR, -}); +type InternalDateRangerType = typeof InternalDateRanger; + +export interface DateRangerInstance extends InternalDateRangerType { + NEAR_1_MINUTES: typeof NEAR_1_MINUTES; + NEAR_5_MINUTES: typeof NEAR_5_MINUTES; + NEAR_10_MINUTES: typeof NEAR_10_MINUTES; + NEAR_20_MINUTES: typeof NEAR_20_MINUTES; + NEAR_30_MINUTES: typeof NEAR_30_MINUTES; + NEAR_1_HOURS: typeof NEAR_1_HOURS; + NEAR_2_HOURS: typeof NEAR_2_HOURS; + NEAR_3_HOURS: typeof NEAR_3_HOURS; + NEAR_6_HOURS: typeof NEAR_6_HOURS; + NEAR_12_HOURS: typeof NEAR_12_HOURS; + TODAY: typeof TODAY; + LAST_1_DAY: typeof LAST_1_DAY; + LAST_3_DAYS: typeof LAST_3_DAYS; + LAST_WEEK: typeof LAST_WEEK; + YESTERDAY: typeof YESTERDAY; + THIS_WEEK: typeof THIS_WEEK; + THIS_MONTH: typeof THIS_MONTH; + LAST_MONTH: typeof LAST_MONTH; + THIS_YEAR: typeof THIS_YEAR; + LAST_YEAR: typeof LAST_YEAR; + NEXT_YEAR: typeof NEXT_YEAR; +} + +const DateRanger = InternalDateRanger as DateRangerInstance; + +// 内置 ranges +DateRanger.NEAR_1_MINUTES = NEAR_1_MINUTES; +DateRanger.NEAR_5_MINUTES = NEAR_5_MINUTES; +DateRanger.NEAR_10_MINUTES = NEAR_10_MINUTES; +DateRanger.NEAR_20_MINUTES = NEAR_20_MINUTES; +DateRanger.NEAR_30_MINUTES = NEAR_30_MINUTES; +DateRanger.NEAR_1_HOURS = NEAR_1_HOURS; +DateRanger.NEAR_2_HOURS = NEAR_2_HOURS; +DateRanger.NEAR_3_HOURS = NEAR_3_HOURS; +DateRanger.NEAR_6_HOURS = NEAR_6_HOURS; +DateRanger.NEAR_12_HOURS = NEAR_12_HOURS; +DateRanger.TODAY = TODAY; +DateRanger.LAST_1_DAY = LAST_1_DAY; +DateRanger.LAST_3_DAYS = LAST_3_DAYS; +DateRanger.YESTERDAY = YESTERDAY; +DateRanger.THIS_WEEK = THIS_WEEK; +DateRanger.LAST_WEEK = LAST_WEEK; +DateRanger.THIS_MONTH = THIS_MONTH; +DateRanger.LAST_MONTH = LAST_MONTH; +DateRanger.THIS_YEAR = THIS_YEAR; +DateRanger.LAST_YEAR = LAST_YEAR; +DateRanger.NEXT_YEAR = NEXT_YEAR; export default DateRanger; From 0b49076e8180ad60816d8a160b766044486dc897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E8=B6=85?= Date: Wed, 15 Jan 2025 11:03:50 +0800 Subject: [PATCH 2/3] type(ui): fix locale wrapper type --- packages/ui/src/DateRanger/Ranger.tsx | 9 +++++- packages/ui/src/DateRanger/demo/basic.tsx | 4 +-- .../src/DateRanger/demo/updateCurrentTime.tsx | 2 +- .../FullscreenBox/demo/ListToolbarDemo.tsx | 2 +- packages/ui/src/Ranger/index.ts | 32 ++++++++++++++++++- packages/ui/src/TagSelect/Group.tsx | 15 +++++---- packages/ui/src/locale/LocaleWrapper.tsx | 9 ++++-- 7 files changed, 58 insertions(+), 15 deletions(-) diff --git a/packages/ui/src/DateRanger/Ranger.tsx b/packages/ui/src/DateRanger/Ranger.tsx index f02242fca..82f6fe2c5 100644 --- a/packages/ui/src/DateRanger/Ranger.tsx +++ b/packages/ui/src/DateRanger/Ranger.tsx @@ -1,3 +1,4 @@ +import type { ElementRef } from 'react'; import React, { useEffect, useRef, useState, useImperativeHandle } from 'react'; import { Button, @@ -91,9 +92,15 @@ export interface DateRangerProps locale?: any; } +export type DateRangerHandle = { + updateCurrentTime: () => void; +}; + +export type DateRangerHandleRef = ElementRef; + const prefix = getPrefix('date-ranger'); -const Ranger = React.forwardRef((props: DateRangerProps, ref) => { +const Ranger = React.forwardRef((props, ref) => { const { selects = [ NEAR_1_MINUTES, diff --git a/packages/ui/src/DateRanger/demo/basic.tsx b/packages/ui/src/DateRanger/demo/basic.tsx index f3919bec3..c9158fd06 100644 --- a/packages/ui/src/DateRanger/demo/basic.tsx +++ b/packages/ui/src/DateRanger/demo/basic.tsx @@ -7,7 +7,7 @@ export default () => { const options = [ { label: 'hasRewind', value: 'hasRewind' }, { label: 'hasForward', value: 'hasForward' }, - { label: 'hasNow', value: 'hasNow' }, + { label: 'hasSync', value: 'hasSync' }, ]; const [state, setState] = useState(options.map(item => item.value)); @@ -36,7 +36,7 @@ export default () => { allowClear={true} hasForward={getValue('hasForward')} hasRewind={getValue('hasRewind')} - hasNow={getValue('hasNow')} + hasSync={getValue('hasSync')} /> ); diff --git a/packages/ui/src/DateRanger/demo/updateCurrentTime.tsx b/packages/ui/src/DateRanger/demo/updateCurrentTime.tsx index 8dabdc190..27a997823 100644 --- a/packages/ui/src/DateRanger/demo/updateCurrentTime.tsx +++ b/packages/ui/src/DateRanger/demo/updateCurrentTime.tsx @@ -8,7 +8,7 @@ type TimeRangeRef = { }; export default () => { - const ref = useRef(); + const ref = useRef(null); const [timeRange, setTimeRange] = useState([]); const format = 'YYYY-MM-DD HH:mm:ss'; return ( diff --git a/packages/ui/src/FullscreenBox/demo/ListToolbarDemo.tsx b/packages/ui/src/FullscreenBox/demo/ListToolbarDemo.tsx index d0470cb28..8a5dca366 100644 --- a/packages/ui/src/FullscreenBox/demo/ListToolbarDemo.tsx +++ b/packages/ui/src/FullscreenBox/demo/ListToolbarDemo.tsx @@ -8,7 +8,7 @@ import { SimpleTable } from './SimpleTable'; export default () => { const [fullscreen, setFullscreen] = useState(false); - const boxRef = useRef(); + const boxRef = useRef>(); function handleFullscreenChange(fs) { setFullscreen(fs); diff --git a/packages/ui/src/Ranger/index.ts b/packages/ui/src/Ranger/index.ts index 41183816d..0eb54e8c0 100644 --- a/packages/ui/src/Ranger/index.ts +++ b/packages/ui/src/Ranger/index.ts @@ -30,7 +30,37 @@ import InternalRanger from './Ranger'; export * from './QuickPicker'; export * from './Ranger'; -const Ranger = InternalRanger; +type InternalRangerType = typeof InternalRanger; + +export interface RangerInstance extends InternalRangerType { + QuickPicker: typeof QuickPicker; + NEAR_1_MINUTES: typeof NEAR_1_MINUTES; + NEAR_5_MINUTES: typeof NEAR_5_MINUTES; + NEAR_10_MINUTES: typeof NEAR_10_MINUTES; + NEAR_20_MINUTES: typeof NEAR_20_MINUTES; + NEAR_30_MINUTES: typeof NEAR_30_MINUTES; + NEAR_1_HOURS: typeof NEAR_1_HOURS; + NEAR_2_HOURS: typeof NEAR_2_HOURS; + NEAR_3_HOURS: typeof NEAR_3_HOURS; + NEAR_6_HOURS: typeof NEAR_6_HOURS; + TODAY: typeof TODAY; + YESTERDAY: typeof YESTERDAY; + TOMORROW: typeof TOMORROW; + THIS_WEEK: typeof THIS_WEEK; + LAST_WEEK: typeof LAST_WEEK; + NEXT_WEEK: typeof NEXT_WEEK; + THIS_MONTH: typeof THIS_MONTH; + LAST_MONTH: typeof LAST_MONTH; + NEXT_MONTH: typeof NEXT_MONTH; + THIS_QUARTER: typeof THIS_QUARTER; + LAST_QUARTER: typeof LAST_QUARTER; + NEXT_QUARTER: typeof NEXT_QUARTER; + THIS_YEAR: typeof THIS_YEAR; + LAST_YEAR: typeof LAST_YEAR; + NEXT_YEAR: typeof NEXT_YEAR; +} + +const Ranger = InternalRanger as RangerInstance; // 内置 ranges Ranger.NEAR_1_MINUTES = NEAR_1_MINUTES; diff --git a/packages/ui/src/TagSelect/Group.tsx b/packages/ui/src/TagSelect/Group.tsx index c36f806c6..f30b69cb0 100644 --- a/packages/ui/src/TagSelect/Group.tsx +++ b/packages/ui/src/TagSelect/Group.tsx @@ -1,6 +1,7 @@ import classNames from 'classnames'; import { getPrefix } from '../_util'; -import React, { ReactNode, useMemo, useState, useEffect } from 'react'; +import type { ReactNode } from 'react'; +import React, { useMemo, useState, useEffect } from 'react'; import TagSelectContext from './TagSelectContext'; import Item from './Item'; import useStyle from './style'; @@ -21,11 +22,11 @@ export interface TagSelectGroupProps { disabled?: boolean; className?: string; multiple?: boolean; - defaultValue?: TagSelectValueType | Array; - value?: TagSelectValueType | Array; + defaultValue?: TagSelectValueType | TagSelectValueType[]; + value?: TagSelectValueType | TagSelectValueType[]; size?: string; - options?: Array; - onChange?: (value: Array | TagSelectValueType) => void; + options?: (TagSelectOptionType | string | number)[]; + onChange?: (value: TagSelectValueType[] | TagSelectValueType) => void; } function toArray(value) { @@ -50,10 +51,10 @@ const Group: React.FC = ({ }) => { const prefix = getPrefix('tag-select'); const { wrapSSR, hashId } = useStyle(prefix); - const [value, setValue] = useState>( + const [value, setValue] = useState( toArray(defaultValue || restProps.value) ); - const [registeredValues, setRegisteredValues] = React.useState>([]); + const [registeredValues, setRegisteredValues] = React.useState([]); const registerValue = (val: TagSelectValueType) => { setRegisteredValues(prev => [...prev, val]); diff --git a/packages/ui/src/locale/LocaleWrapper.tsx b/packages/ui/src/locale/LocaleWrapper.tsx index c162aa41a..a8c195eb3 100644 --- a/packages/ui/src/locale/LocaleWrapper.tsx +++ b/packages/ui/src/locale/LocaleWrapper.tsx @@ -12,8 +12,13 @@ export interface LocaleWrapperInput { defaultLocale: any; } +type CTR = + T extends React.ForwardRefExoticComponent> ? R : never; + export default ({ componentName, defaultLocale }: LocaleWrapperInput) => - (BaseComponent: React.ComponentType) => { + ( + BaseComponent: React.ForwardRefExoticComponent | React.ComponentType + ) => { type WrappedComponentProps = BaseProps & { forwardedRef: Ref }; class Hoc extends React.Component { @@ -49,7 +54,7 @@ export default ({ componentName, defaultLocale }: LocaleWrapperInput) => // 高阶组件需要转发ref // 参考: https://zh-hans.reactjs.org/docs/forwarding-refs.html#forwarding-refs-in-higher-order-components - const ForwardComponent = React.forwardRef( + const ForwardComponent = React.forwardRef, BaseProps>( // @ts-ignore (props: BaseProps, ref) => ); From 9c54950addda71ea2a4e2a21563b84faaaa6ff15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E8=B6=85?= Date: Thu, 16 Jan 2025 17:19:12 +0800 Subject: [PATCH 3/3] type(ui): [date-ranger] remove type assertion --- packages/ui/src/DateRanger/Ranger.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/src/DateRanger/Ranger.tsx b/packages/ui/src/DateRanger/Ranger.tsx index 82f6fe2c5..0f88205f3 100644 --- a/packages/ui/src/DateRanger/Ranger.tsx +++ b/packages/ui/src/DateRanger/Ranger.tsx @@ -581,4 +581,4 @@ const Ranger = React.forwardRef((props, ref) export default LocaleWrapper({ componentName: 'DateRanger', defaultLocale: zhCN, -})(Ranger) as typeof Ranger; +})(Ranger);