浏览代码

Fix strict ts (#314)

* fix: locale interface error when tscofnig strict: true

* fix: tree interface error when strict: true

* fix: foundation/utils/log warning about process when strict: true

* chore: [Cascader/Checkbox] fix ts warning when strict

* fix: ts strict

* fix: Rating & Slider ts error in strict mode

* fix: [Upload] ts error

* fix: [Steps] ts error

* fix: [AutoComplete] interface error when strict:true

* fix: configProvider consumer ts error when strict: true

* fix(pagination): ts definition

* fix(typescript): DatePicker,TimePicker,Table,ScrollList

* fix(tabs): ts definition

* fix(calendar): ts definition

* v2.0.9-alpha.1

* fix: [select] ts error of select/utils

* fix: [button] ts error of buttonGroup

* fix: fix ts

* fix: [select] foundation type check when strict:true

* fix: [form] skip strict check of withField ref type check

* v2.0.9-alpha.2

* chore: format script/release & tsconfig in root

* fix: [Icon] ts strict error

* fix: [Collapse] ts check error when using in vite default ts setting; add @types/react-window as dependence to avoid compile error in vite

* v2.0.9-alpha.3

* fix(tabbar): ts definition

* fix: [scrollItem] ts check when using in vite

* v2.0.9-alpha.4

* fix: [form] update withField type define, remove some ts-ignore comment

* v2.0.9-alpha.5

* fix: lack interface export in upload; remove useless define of buttonGroup

Co-authored-by: chenyuling <[email protected]>
Co-authored-by: 代强 <[email protected]>
Co-authored-by: tank0317 <[email protected]>
Co-authored-by: yanqi.xu <[email protected]>
Co-authored-by: zwlafk <[email protected]>
Co-authored-by: 走鹃 <[email protected]>
pointhalo 3 年之前
父节点
当前提交
ef2531c8be
共有 58 个文件被更改,包括 269 次插入268 次删除
  1. 2 0
      .eslintrc.js
  2. 3 1
      packages/semi-foundation/calendar/foundation.ts
  3. 1 1
      packages/semi-foundation/collapse/foundation.ts
  4. 2 2
      packages/semi-foundation/pagination/foundation.ts
  5. 3 3
      packages/semi-foundation/scrollList/itemFoundation.ts
  6. 4 3
      packages/semi-foundation/select/foundation.ts
  7. 1 1
      packages/semi-foundation/table/utils.ts
  8. 1 1
      packages/semi-foundation/treeSelect/foundation.ts
  9. 3 1
      packages/semi-foundation/utils/log.ts
  10. 9 5
      packages/semi-icons/src/components/Icon.tsx
  11. 2 1
      packages/semi-icons/tsconfig.json
  12. 15 13
      packages/semi-ui/autoComplete/index.tsx
  13. 2 1
      packages/semi-ui/button/buttonGroup.tsx
  14. 3 3
      packages/semi-ui/calendar/dayCalendar.tsx
  15. 3 3
      packages/semi-ui/calendar/monthCalendar.tsx
  16. 3 3
      packages/semi-ui/calendar/rangeCalendar.tsx
  17. 3 3
      packages/semi-ui/calendar/weekCalendar.tsx
  18. 1 1
      packages/semi-ui/cascader/index.tsx
  19. 1 1
      packages/semi-ui/checkbox/checkboxGroup.tsx
  20. 1 1
      packages/semi-ui/collapse/index.tsx
  21. 11 10
      packages/semi-ui/datePicker/_story/datePicker.stories.tsx
  22. 1 1
      packages/semi-ui/datePicker/index.tsx
  23. 4 4
      packages/semi-ui/datePicker/yearAndMonth.tsx
  24. 1 2
      packages/semi-ui/form/baseForm.tsx
  25. 0 19
      packages/semi-ui/form/field.tsx
  26. 4 5
      packages/semi-ui/form/hoc/withField.tsx
  27. 2 2
      packages/semi-ui/layout/Sider.tsx
  28. 5 5
      packages/semi-ui/locale/localeConsumer.tsx
  29. 8 3
      packages/semi-ui/modal/useModal/HookModal.tsx
  30. 4 6
      packages/semi-ui/modal/useModal/index.tsx
  31. 2 2
      packages/semi-ui/notification/index.tsx
  32. 1 0
      packages/semi-ui/package.json
  33. 1 1
      packages/semi-ui/rating/index.tsx
  34. 1 0
      packages/semi-ui/resizeObserver/index.tsx
  35. 21 19
      packages/semi-ui/scrollList/scrollItem.tsx
  36. 3 3
      packages/semi-ui/select/index.tsx
  37. 3 3
      packages/semi-ui/select/option.tsx
  38. 3 1
      packages/semi-ui/select/utils.tsx
  39. 2 2
      packages/semi-ui/sideSheet/SideSheetContent.tsx
  40. 4 4
      packages/semi-ui/sideSheet/index.tsx
  41. 2 2
      packages/semi-ui/slider/index.tsx
  42. 2 2
      packages/semi-ui/steps/basicSteps.tsx
  43. 4 4
      packages/semi-ui/steps/fillSteps.tsx
  44. 2 2
      packages/semi-ui/steps/navSteps.tsx
  45. 5 5
      packages/semi-ui/table/Body/index.tsx
  46. 1 1
      packages/semi-ui/table/ResizableTable.tsx
  47. 1 1
      packages/semi-ui/tabs/TabBar.tsx
  48. 11 10
      packages/semi-ui/tabs/index.tsx
  49. 12 7
      packages/semi-ui/timePicker/Combobox.tsx
  50. 1 1
      packages/semi-ui/timePicker/TimePicker.tsx
  51. 1 1
      packages/semi-ui/timePicker/index.tsx
  52. 2 1
      packages/semi-ui/treeSelect/index.tsx
  53. 2 2
      packages/semi-ui/tsconfig.json
  54. 3 17
      packages/semi-ui/upload/fileCard.tsx
  55. 3 57
      packages/semi-ui/upload/index.tsx
  56. 59 0
      packages/semi-ui/upload/interface.ts
  57. 14 14
      scripts/release.js
  58. 0 1
      tsconfig.json

+ 2 - 0
.eslintrc.js

@@ -66,6 +66,8 @@ module.exports = {
                 '@typescript-eslint/no-var-requires': 'warn',
                 '@typescript-eslint/no-inferrable-types': 'off',
                 '@typescript-eslint/no-this-alias': 'off',
+                 // In scenarios where specific rest props need to be passed, some keys may be taken out first, so set 'no-unused-vars' to off
+                '@typescript-eslint/no-unused-vars': 'off',
                 'import/no-unresolved': 'off',
                 'semi': ['error', 'always'],
                 'keyword-spacing': ["error", { "before": true, "after": true }]

+ 3 - 1
packages/semi-foundation/calendar/foundation.ts

@@ -83,11 +83,13 @@ export type MonthData = Record<number, DateObj[]>;
 //     cacheEventKeys: (cachedKeys: Array<string>) => void;
 // }
 
+export type ParsedEventsType = ParsedEvents | ParsedEventsWithArray | MonthlyEvent;
+
 export interface CalendarAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
     updateCurrPos?: (currPos: number) => void;
     updateShowCurrTime?: () => void;
     updateScrollHeight?: (scrollHeight: number) => void;
-    setParsedEvents?: (parsedEvents: ParsedEvents | ParsedEventsWithArray | MonthlyEvent) => void;
+    setParsedEvents?: (parsedEvents: ParsedEventsType) => void;
     cacheEventKeys?: (cachedKeys: Array<string>) => void;
     setRangeData?: (data: RangeData) => void;
     getRangeData?: () => RangeData;

+ 1 - 1
packages/semi-foundation/collapse/foundation.ts

@@ -23,7 +23,7 @@ export interface CollapseState{
 }
 
 export interface CollapseAdapter extends DefaultAdapter<CollapseProps, CollapseState>{
-    handleChange: (...args: ArgsType<CollapseProps['onChange']>) => ReturnType<CollapseProps['onChange']>;
+    handleChange: (activeKey: CollapseProps['activeKey'], e: any) => void;
     // getStates: () => CollapseState;
     // getProps: () => CollapseProps;
     addActiveKey: (newSet: CollapseState['activeSet']) => void;

+ 2 - 2
packages/semi-foundation/pagination/foundation.ts

@@ -12,9 +12,9 @@ export interface PaginationAdapter<P = Record<string, any>, S = Record<string, a
     setCurrentPage: (pageIndex: number) => void;
     registerKeyDownHandler: (handler: KeyDownHandler) => void;
     unregisterKeyDownHandler: (handler: KeyDownHandler) => void;
-    notifyPageChange: (pageIndex: number | string) => void;
+    notifyPageChange: (pageIndex: number) => void;
     notifyPageSizeChange: (pageSize: number) => void;
-    notifyChange: (pageIndex: number | string, pageSize: number) => void;
+    notifyChange: (pageIndex: number, pageSize: number) => void;
 }
 
 export type PageRenderText = number | '...';

+ 3 - 3
packages/semi-foundation/scrollList/itemFoundation.ts

@@ -11,16 +11,16 @@ export interface Item {
     disabled?: boolean;
 }
 
-export interface ScrollItemAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
+export interface ScrollItemAdapter<P = Record<string, any>, S = Record<string, any>, I = Item> extends DefaultAdapter<P, S> {
     setPrependCount: (prependCount: number) => void;
     setAppendCount: (appendCount: number) => void;
     setSelectedNode: (el: HTMLElement) => void;
     isDisabledIndex: (i: number) => boolean;
-    notifySelectItem: (data: Item) => void;
+    notifySelectItem: (data: I) => void;
     scrollToCenter: (selectedNode: Element, scrollWrapper?: Element, duration?: number) => void;
 }
 
-export default class ItemFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ScrollItemAdapter<P, S>, P, S> {
+export default class ItemFoundation<P = Record<string, any>, S = Record<string, any>, I = Item> extends BaseFoundation<ScrollItemAdapter<P, S, I>, P, S> {
     _cachedSelectedNode: HTMLElement = null;
 
     selectIndex(index: number, listWrapper: HTMLElement) {

+ 4 - 3
packages/semi-foundation/select/foundation.ts

@@ -45,8 +45,9 @@ export interface SelectAdapter<P = Record<string, any>, S = Record<string, any>>
     updateHovering(isHover: boolean): void;
     updateScrollTop(): void;
 }
-type PropValue = string | number | Record<string, any>;
 
+type LabelValue = string | number;
+type PropValue = LabelValue | Record<string, any>;
 export default class SelectFoundation extends BaseFoundation<SelectAdapter> {
 
     constructor(adapter: SelectAdapter) {
@@ -258,11 +259,11 @@ export default class SelectFoundation extends BaseFoundation<SelectAdapter> {
 
         // When onChangeWithObject is true
         if (onChangeWithObject && propValueIsArray) {
-            selectedValues = propValue.map((item: BasicOptionProps) => item.value) as any;
+            selectedValues = (propValue as BasicOptionProps[]).map(item => item.value);
         }
 
         if (propValueIsArray && selectedValues.length) {
-            selectedValues.forEach((selectedValue: string, i: number) => {
+            (selectedValues as LabelValue[]).forEach((selectedValue, i: number) => {
                 // The current value exists in the current optionList
                 const index = originalOptions.findIndex(option => option.value === selectedValue);
                 if (index !== -1) {

+ 1 - 1
packages/semi-foundation/table/utils.ts

@@ -166,7 +166,7 @@ export function isSelectionColumn(column: Record<string, any>) {
     return get(column, 'key') === strings.DEFAULT_KEY_COLUMN_SELECTION;
 }
 
-export function filterColumns(columns: Record<string, any>[], ignoreKeys = [strings.DEFAULT_KEY_COLUMN_SCROLLBAR]) {
+export function filterColumns(columns: Record<string, any>[], ignoreKeys = [strings.DEFAULT_KEY_COLUMN_SCROLLBAR as string]) {
     return filter(columns, col => !ignoreKeys.includes(col.key));
 }
 

+ 1 - 1
packages/semi-foundation/treeSelect/foundation.ts

@@ -128,7 +128,7 @@ export interface BasicTreeSelectProps extends Pick<BasicTreeProps,
     searchRender?: (inputProps: any) => any;
     renderSelectedItem?: BasicRenderSelectedItem;
     getPopupContainer?: () => HTMLElement;
-    triggerRender?: (props: BasicTriggerRenderProps) => any;
+    // triggerRender?: (props: BasicTriggerRenderProps) => any;
     onBlur?: (e: any) => void;
     onChange?: BasicOnChange;
     onFocus?: (e: any) => void;

+ 3 - 1
packages/semi-foundation/utils/log.ts

@@ -1,5 +1,7 @@
+import { get } from 'lodash-es';
+
 const log = (text: any, ...rest: any[]) => {
-    if (process.env.NODE_ENV === 'development') {
+    if (get(process, 'env.NODE_ENV') === 'development') {
         console.log(text, ...rest);
     }
 };

+ 9 - 5
packages/semi-icons/src/components/Icon.tsx

@@ -1,4 +1,4 @@
-import React, { ReactNode, ReactElement, CSSProperties, DetailedHTMLProps, Ref, ComponentType, ForwardRefExoticComponent } from 'react';
+import React, { ReactNode, Ref, CSSProperties, DetailedHTMLProps, ComponentType } from 'react';
 import { BASE_CLASS_PREFIX } from '../env';
 import cls from 'classnames';
 import '../styles/icon.scss';
@@ -14,7 +14,7 @@ export interface IconProps extends DetailedHTMLProps<React.HTMLAttributes<HTMLSp
     type?: string;
 }
 
-const Icon: ForwardRefExoticComponent<IconProps> & { elementType?: string } = React.forwardRef((props: IconProps, ref: Ref<HTMLSpanElement>): ReactElement => {
+const Icon = React.forwardRef<HTMLSpanElement, IconProps>((props, ref) => {
     const { svg, spin = false, rotate, style, className, prefixCls = BASE_CLASS_PREFIX, type, size = 'default', ...restProps } = props;
     const classes = cls(`${prefixCls}-icon`, {
         [`${prefixCls}-icon-extra-small`]: size === 'extra-small', // 8x8
@@ -34,11 +34,15 @@ const Icon: ForwardRefExoticComponent<IconProps> & { elementType?: string } = Re
     return <span role="img" ref={ref} className={classes} style={outerStyle} {...restProps}>{svg}</span>;
 });
 
+// @ts-ignore used to judge whether it is a semi-icon in semi-ui
+// custom icon case
 Icon.elementType = 'Icon';
 
-const convertIcon = (Svg: ComponentType, iconType: string): ForwardRefExoticComponent<Omit<IconProps, 'svg' | 'type'>> & { elementType?: string } => {
-    const InnerIcon: ForwardRefExoticComponent<Omit<IconProps, 'svg' | 'type'>> & { elementType?: string } = React.forwardRef((props: Omit<IconProps, 'svg' | 'type'>, ref: Ref<HTMLSpanElement>): ReactElement =>
-        <Icon svg={React.createElement(Svg)} type={iconType} ref={ref} {...props} />);
+const convertIcon = (Svg: ComponentType, iconType: string) => {
+    const InnerIcon = React.forwardRef<HTMLSpanElement, Omit<IconProps, 'svg' | 'type'>>((props, ref) =>
+        <Icon svg={React.createElement(Svg)} type={iconType} ref={ref as any} {...props} />);
+    // @ts-ignore used to judge whether it is a semi-icon in semi-ui 
+    // builtin icon case
     InnerIcon.elementType = 'Icon';
     return InnerIcon;
 };

+ 2 - 1
packages/semi-icons/tsconfig.json

@@ -16,9 +16,10 @@
         "experimentalDecorators": true,
         "noImplicitReturns": true,
         "noImplicitThis": false,
-        "strictNullChecks": false,
+        "strictNullChecks": true,
         "esModuleInterop": true,
         "skipLibCheck": true,
+        "strict": true,
         "declaration": true
     },
     "include": ["**/*.tsx", "**/*.ts"],

+ 15 - 13
packages/semi-ui/autoComplete/index.tsx

@@ -36,15 +36,17 @@ export interface BaseDataItem extends DataItem {
     label?: React.ReactNode;
 }
 
-export interface AutoCompleteProps<Item extends BaseDataItem = BaseDataItem> {
+export type AutoCompleteItems = BaseDataItem | string | number;
+
+export interface AutoCompleteProps<T extends AutoCompleteItems> {
     autoAdjustOverflow?: boolean;
     autoFocus?: boolean;
     className?: string;
     children?: React.ReactNode;
-    data?: Array<string | Item | number>;
+    data?: T[];
     disabled?: boolean;
     defaultOpen?: boolean;
-    defaultValue?: string | number | Item;
+    defaultValue?: T;
     defaultActiveFirstOption?: boolean;
     dropdownMatchSelectWidth?: boolean;
     dropdownClassName?: string;
@@ -61,7 +63,7 @@ export interface AutoCompleteProps<Item extends BaseDataItem = BaseDataItem> {
     onBlur?: (e: React.FocusEvent) => void;
     onChange?: (value: string | number) => void;
     onSearch?: (inputValue: string) => void;
-    onSelect?: (value: string | Item | number) => void;
+    onSelect?: (value: T) => void;
     onClear?: () => void;
     onChangeWithObject?: boolean;
     onSelectWithObject?: boolean;
@@ -69,8 +71,8 @@ export interface AutoCompleteProps<Item extends BaseDataItem = BaseDataItem> {
     prefix?: React.ReactNode;
     placeholder?: string;
     position?: Position;
-    renderItem?: (option: Item | string) => React.ReactNode;
-    renderSelectedItem?: (option: Item) => string;
+    renderItem?: (option: T) => React.ReactNode;
+    renderSelectedItem?: (option: T) => string;
     size?: 'small' | 'default' | 'large';
     style?: React.CSSProperties;
     suffix?: React.ReactNode;
@@ -97,7 +99,7 @@ interface AutoCompleteState {
     keyboardEventSet?: KeyboardEventType;
 }
 
-class AutoComplete extends BaseComponent<AutoCompleteProps, AutoCompleteState> {
+class AutoComplete<T extends AutoCompleteItems> extends BaseComponent<AutoCompleteProps<T>, AutoCompleteState> {
     static propTypes = {
         autoFocus: PropTypes.bool,
         autoAdjustOverflow: PropTypes.bool,
@@ -143,7 +145,7 @@ class AutoComplete extends BaseComponent<AutoCompleteProps, AutoCompleteState> {
 
     static Option = Option;
 
-    static defaultProps: Partial<AutoCompleteProps> = {
+    static defaultProps = {
         stopPropagation: true,
         motion: true,
         zIndex: popoverNumbers.DEFAULT_Z_INDEX,
@@ -176,7 +178,7 @@ class AutoComplete extends BaseComponent<AutoCompleteProps, AutoCompleteState> {
 
     private clickOutsideHandler: () => void | null;
 
-    constructor(props: AutoCompleteProps) {
+    constructor(props: AutoCompleteProps<T>) {
         super(props);
         this.foundation = new AutoCompleteFoundation(this.adapter);
         const initRePosKey = 1;
@@ -207,7 +209,7 @@ class AutoComplete extends BaseComponent<AutoCompleteProps, AutoCompleteState> {
         );
     }
 
-    get adapter(): AutoCompleteAdapter<AutoCompleteProps, AutoCompleteState> {
+    get adapter(): AutoCompleteAdapter<AutoCompleteProps<T>, AutoCompleteState> {
         const keyboardAdapter = {
             registerKeyDown: (cb: any): void => {
                 const keyboardEventSet = {
@@ -250,8 +252,8 @@ class AutoComplete extends BaseComponent<AutoCompleteProps, AutoCompleteState> {
             notifyChange: value => {
                 this.props.onChange(value);
             },
-            notifySelect: (option: StateOptionItem | string): void => {
-                this.props.onSelect(option);
+            notifySelect: (option: StateOptionItem | string | number): void => {
+                this.props.onSelect(option as T);
             },
             notifyDropdownVisibleChange: (isVisible: boolean): void => {
                 this.props.onDropdownVisibleChange(isVisible);
@@ -281,7 +283,7 @@ class AutoComplete extends BaseComponent<AutoCompleteProps, AutoCompleteState> {
         this.foundation.destroy();
     }
 
-    componentDidUpdate(prevProps: AutoCompleteProps, prevState: AutoCompleteState) {
+    componentDidUpdate(prevProps: AutoCompleteProps<T>, prevState: AutoCompleteState) {
         if (!isEqual(this.props.data, prevProps.data)) {
             this.foundation.handleDataChange(this.props.data);
         }

+ 2 - 1
packages/semi-ui/button/buttonGroup.tsx

@@ -7,6 +7,7 @@ import { Type, Size } from './Button';
 import '@douyinfe/semi-foundation/button/button.scss';
 
 export type Theme = 'solid' | 'borderless' | 'light';
+
 export interface ButtonGroupProps extends BaseProps {
     disabled?: boolean;
     type?: Type;
@@ -37,7 +38,7 @@ export default class ButtonGroup extends BaseComponent<ButtonGroupProps> {
         let inner;
 
         if (children) {
-            inner = (Array.isArray(children) ? children : [children]).map((itm: React.ReactElement, index) =>
+            inner = ((Array.isArray(children) ? children : [children]) as React.ReactElement[]).map((itm, index) =>
                 React.cloneElement(itm, { disabled, size, type, ...itm.props, ...rest, key: index })
             );
         }

+ 3 - 3
packages/semi-ui/calendar/dayCalendar.tsx

@@ -2,7 +2,7 @@ import React from 'react';
 import { isEqual } from 'lodash-es';
 import cls from 'classnames';
 import PropTypes from 'prop-types';
-import CalendarFoundation, { CalendarAdapter, ParsedEventsWithArray } from '@douyinfe/semi-foundation/calendar/foundation';
+import CalendarFoundation, { CalendarAdapter, ParsedEventsType, ParsedEventsWithArray } from '@douyinfe/semi-foundation/calendar/foundation';
 import { cssClasses } from '@douyinfe/semi-foundation/calendar/constants';
 import DayCol from './dayCol';
 import TimeCol from './timeCol';
@@ -77,8 +77,8 @@ export default class DayCalendar extends BaseComponent<DayCalendarProps, DayCale
             updateScrollHeight: scrollHeight => {
                 this.setState({ scrollHeight });
             },
-            setParsedEvents: (parsedEvents: ParsedEventsWithArray) => {
-                this.setState({ parsedEvents });
+            setParsedEvents: (parsedEvents: ParsedEventsType) => {
+                this.setState({ parsedEvents: parsedEvents as ParsedEventsWithArray });
             },
             cacheEventKeys: cachedKeys => {
                 this.setState({ cachedKeys });

+ 3 - 3
packages/semi-ui/calendar/monthCalendar.tsx

@@ -5,7 +5,7 @@ import { isEqual } from 'lodash-es';
 import PropTypes from 'prop-types';
 import { IconClose } from '@douyinfe/semi-icons';
 // eslint-disable-next-line max-len
-import CalendarFoundation, { CalendarAdapter, EventObject, MonthData, MonthlyEvent, ParsedRangeEvent } from '@douyinfe/semi-foundation/calendar/foundation';
+import CalendarFoundation, { CalendarAdapter, EventObject, MonthData, MonthlyEvent, ParsedEventsType, ParsedEventsWithArray, ParsedRangeEvent } from '@douyinfe/semi-foundation/calendar/foundation';
 import { cssClasses } from '@douyinfe/semi-foundation/calendar/constants';
 import { DateObj } from '@douyinfe/semi-foundation/calendar/eventUtil';
 import LocaleConsumer from '../locale/localeConsumer';
@@ -118,8 +118,8 @@ export default class monthCalendar extends BaseComponent<MonthCalendarProps, Mon
                     showCard: { ...updates }
                 }));
             },
-            setParsedEvents: (parsedEvents: MonthlyEvent) => {
-                this.setState({ parsedEvents });
+            setParsedEvents: (parsedEvents: ParsedEventsType) => {
+                this.setState({ parsedEvents: parsedEvents as MonthlyEvent });
             },
             setItemLimit: itemLimit => {
                 this.setState({ itemLimit });

+ 3 - 3
packages/semi-ui/calendar/rangeCalendar.tsx

@@ -2,7 +2,7 @@ import React from 'react';
 import cls from 'classnames';
 import PropTypes from 'prop-types';
 // eslint-disable-next-line max-len
-import CalendarFoundation, { ParsedEvents, CalendarAdapter, RangeData, ParsedRangeEvent } from '@douyinfe/semi-foundation/calendar/foundation';
+import CalendarFoundation, { ParsedEvents, CalendarAdapter, RangeData, ParsedRangeEvent, ParsedEventsType } from '@douyinfe/semi-foundation/calendar/foundation';
 import LocaleConsumer from '../locale/localeConsumer';
 import localeContext from '../locale/context';
 import { cssClasses } from '@douyinfe/semi-foundation/calendar/constants';
@@ -90,8 +90,8 @@ export default class RangeCalendar extends BaseComponent<RangeCalendarProps, Ran
             updateScrollHeight: scrollHeight => {
                 this.setState({ scrollHeight });
             },
-            setParsedEvents: (parsedEvents: ParsedEvents) => {
-                this.setState({ parsedEvents });
+            setParsedEvents: (parsedEvents: ParsedEventsType) => {
+                this.setState({ parsedEvents: parsedEvents as ParsedEvents });
             },
             cacheEventKeys: cachedKeys => {
                 this.setState({ cachedKeys });

+ 3 - 3
packages/semi-ui/calendar/weekCalendar.tsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import cls from 'classnames';
 import PropTypes from 'prop-types';
-import CalendarFoundation, { CalendarAdapter, EventObject, ParsedEvents, ParsedRangeEvent, WeeklyData } from '@douyinfe/semi-foundation/calendar/foundation';
+import CalendarFoundation, { CalendarAdapter, EventObject, ParsedEvents, ParsedEventsType, ParsedRangeEvent, WeeklyData } from '@douyinfe/semi-foundation/calendar/foundation';
 import LocaleConsumer from '../locale/localeConsumer';
 import localeContext from '../locale/context';
 import { cssClasses } from '@douyinfe/semi-foundation/calendar/constants';
@@ -88,8 +88,8 @@ export default class WeekCalendar extends BaseComponent<WeekCalendarProps, WeekC
             updateScrollHeight: scrollHeight => {
                 this.setState({ scrollHeight });
             },
-            setParsedEvents: (parsedEvents: ParsedEvents) => {
-                this.setState({ parsedEvents });
+            setParsedEvents: (parsedEvents: ParsedEventsType) => {
+                this.setState({ parsedEvents: parsedEvents as ParsedEvents });
             },
             cacheEventKeys: cachedKeys => {
                 this.setState({ cachedKeys });

+ 1 - 1
packages/semi-ui/cascader/index.tsx

@@ -390,7 +390,7 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
                     const formatValuePath: (string | number)[][] = [];
                     normallizedValue.forEach((valueItem: SimpleValueType[]) => {
                         const formatItem: (string | number)[] = onChangeWithObject ?
-                            valueItem.map((i: CascaderData) => i.value) :
+                            (valueItem as CascaderData[]).map(i => i.value) :
                             valueItem as (string | number)[];
                         formatValuePath.push(formatItem);
                     });

+ 1 - 1
packages/semi-ui/checkbox/checkboxGroup.tsx

@@ -144,7 +144,7 @@ class CheckboxGroup extends BaseComponent<CheckboxGroupProps, CheckboxGroupState
                 }
             });
         } else if (children) {
-            inner = React.Children.toArray(children).map((itm: React.ReactElement, index) => React.cloneElement(itm, { key: index }));
+            inner = (React.Children.toArray(children) as React.ReactElement[]).map((itm, index) => React.cloneElement(itm, { key: index }));
         }
 
         return (

+ 1 - 1
packages/semi-ui/collapse/index.tsx

@@ -63,7 +63,7 @@ class Collapse extends BaseComponent<CollapseReactProps, CollapseState> {
     get adapter(): CollapseAdapter {
         return {
             ...super.adapter,
-            handleChange: (...args: ArgsType<CollapseReactProps['onChange']>) => this.props.onChange(...args),
+            handleChange: (activeKey: CollapseProps['activeKey'], e: React.MouseEvent) => this.props.onChange(activeKey, e),
             addActiveKey: (activeSet: CollapseState['activeSet']) => this.setState({ activeSet }),
         };
     }

+ 11 - 10
packages/semi-ui/datePicker/_story/datePicker.stories.tsx

@@ -69,7 +69,7 @@ stories.add('default', () => {
             <>
                 <DatePicker ref={ref} style={{ display: 'inline-block' }} />
                 <DatePicker
-                    type="dateTime"
+                    type='dateTime'
                     presets={presets.map(preset => ({
                         text: preset.text,
                         start: preset.start,
@@ -151,6 +151,7 @@ stories.add('triggerRender', () => {
 
     return (
         <DatePicker
+            ref={ref}
             onChange={onChange}
             value={date}
             format={formatToken}
@@ -184,20 +185,20 @@ stories.add('Form.DatePicker', () => {
             end: new Date(new Date().valueOf() + 1000 * 3600 * 24),
         },
     ];
-    const CustomDatePicker = (props: DatePickerProps & { fieldRef: React.Ref<Object> }) => {
-      const { fieldRef, ...rest } = props;
-      return (
-        <DatePicker {...rest} ref={fieldRef}  />
-      );
-    };
+    // const CustomDatePicker = (props: DatePickerProps & { fieldRef: React.Ref<Object> }) => {
+    //   const { fieldRef, ...rest } = props;
+    //   return (
+    //     <DatePicker {...rest} ref={fieldRef}  />
+    //   );
+    // };
     
-    const CustomFieldDatePicker = withField(CustomDatePicker);
+    // const CustomFieldDatePicker = withField(CustomDatePicker);
 
     return (
       <>
         <DatePicker type="dateRange" ref={ref} />
         <Form>
-        <CustomFieldDatePicker
+        {/* <CustomFieldDatePicker
               type="dateTimeRange"
               field="a"
               label="Form.DatePicker"
@@ -217,7 +218,7 @@ stories.add('Form.DatePicker', () => {
               onBlur={() => {console.log('blur')}}
               style={{ width: 500 }}
               fieldRef={ref2}
-          />
+          /> */}
         </Form>
       </>
     );

+ 1 - 1
packages/semi-ui/datePicker/index.tsx

@@ -35,7 +35,7 @@ export default forwardStatics(
 
         return (
             <ConfigContext.Consumer>
-                {({ timeZone }: { timeZone: string | number }) => (
+                {({ timeZone }: { timeZone?: string | number }) => (
                     <LocaleConsumer componentName={'DatePicker'}>
                         {(locale: Locale['DatePicker'], localeCode: string, dateFnsLocale: Locale['dateFnsLocale']) => (
                             <DatePicker

+ 4 - 4
packages/semi-ui/datePicker/yearAndMonth.tsx

@@ -46,8 +46,8 @@ class YearAndMonth extends BaseComponent<YearAndMonthProps, YearAndMonthState> {
         onSelect: noop,
     };
     foundation: YearAndMonthFoundation;
-    yearRef: React.RefObject<ScrollItem>;
-    monthRef: React.RefObject<ScrollItem>;
+    yearRef: React.RefObject<ScrollItem<YearScrollItem>>;
+    monthRef: React.RefObject<ScrollItem<MonthScrollItem>>;
 
     constructor(props: YearAndMonthProps) {
         super(props);
@@ -117,7 +117,7 @@ class YearAndMonth extends BaseComponent<YearAndMonthProps, YearAndMonthState> {
         const { years, currentYear, currentMonth } = this.state;
         const { disabledDate, localeCode, yearCycled } = this.props;
         const currentDate = setMonth(Date.now(), currentMonth - 1);
-        const list = years.map(({ value, year }) => ({
+        const list: any[] = years.map(({ value, year }) => ({
             year,
             value, // Actual rendered text
             disabled: disabledDate(setYear(currentDate, year)),
@@ -170,7 +170,7 @@ class YearAndMonth extends BaseComponent<YearAndMonthProps, YearAndMonthState> {
             transform = val => `${val }月`;
         }
         // i18n
-        const list = months.map(({ value, month }) => ({
+        const list: MonthScrollItem[] = months.map(({ value, month }) => ({
             month,
             disabled: disabledDate(setMonth(currentDate, month - 1)),
             value: locale.fullMonths[value], // Actual rendered text

+ 1 - 2
packages/semi-ui/form/baseForm.tsx

@@ -122,8 +122,7 @@ class Form extends BaseComponent<BaseFormProps, BaseFormState> {
             formId: getUuidv4(),
         };
         warning(
-            // @ts-ignore special usage
-            props.component && props.render,
+            Boolean(props.component && props.render),
             '[Semi Form] You should not use <Form component> and <Form render> in ths same time; <Form render> will be ignored'
         );
         warning(

+ 0 - 19
packages/semi-ui/form/field.tsx

@@ -49,28 +49,9 @@ const FormRadio = withField(Radio, {
 const FormDatePicker = withField(DatePicker);
 const FormSwitch = withField(Switch, { valueKey: 'checked' });
 const FormSlider = withField(Slider);
-
-
-/**
- * Reasons for using ts-igonre:
- * 
- * 1. TimePicker: The propTypes of the locale is defined as object (it is not necessary and too troublesome to write a complete shapeOf), 
- * but the interface defines a complete type, the two cannot match, and ts will report an error, so skip it here.
- * 
- * 2. Cascader: treeData { label, value } define in PropTypes.shapeOf alreaady declare isRequired, ts still throw error 
- *    【Property is optional in type “InferProps<{ value: Validator<string | number>; label: Validator<any>; }>” but required in type CascaderData】
- *    skip it here.
- * 3. TreeSelect: value same as cascader, skip it here
- * 
- */
-
-// @ts-ignore-next-line
 const FormTimePicker = withField(TimePicker);
-// @ts-ignore-next-line
 const FormTreeSelect = withField(TreeSelect);
-// @ts-ignore-next-line
 const FormCascader = withField(Cascader);
-
 const FormRating = withField(Rating);
 const FormAutoComplete = withField(AutoComplete, { valueKey: 'value', onKeyChangeFnName: 'onChange' });
 const FormUpload = withField(Upload, { valueKey: 'fileList', valuePath: 'fileList', onKeyChangeFnName: 'onChange' });

+ 4 - 5
packages/semi-ui/form/hoc/withField.tsx

@@ -1,4 +1,3 @@
-/* argus-disable unPkgSensitiveInfo */
 /* eslint-disable max-lines-per-function, react-hooks/rules-of-hooks, prefer-const, max-len */
 import React, { useState, useLayoutEffect, useMemo, useRef, forwardRef } from 'react';
 import classNames from 'classnames';
@@ -27,9 +26,10 @@ const prefix = cssClasses.PREFIX;
  */
 
 function withField<
-    C extends React.ComponentType<React.ComponentProps<C>>,
-    T extends React.ComponentType<Subtract<React.ComponentProps<C>, CommonexcludeType> & CommonFieldProps>
->(Component: C, opts?: WithFieldOption): T {
+    C extends React.ElementType,
+    T extends Subtract<React.ComponentProps<C>, CommonexcludeType> & CommonFieldProps,
+    R extends React.ComponentType<T>
+>(Component: C, opts?: WithFieldOption): R {
     let SemiField = (props: any, ref: React.MutableRefObject<any>) => {
         let {
             // condition,
@@ -547,7 +547,6 @@ function withField<
             return useMemo(() => FieldComponent, [...shouldUpdate]);
         } else {
             // Some Custom Component with inner state shouldn't be memo, otherwise the component will not updated when the internal state is updated
-            // Fixed issue 328
             return FieldComponent;
         }
     };

+ 2 - 2
packages/semi-ui/layout/Sider.tsx

@@ -67,7 +67,7 @@ class Sider extends React.PureComponent<SiderProps> {
 
     componentDidMount(): void {
         const { breakpoint } = this.props;
-        const matchBpt: Array<keyof ResponsiveMap> = Object.keys(responsiveMap).filter((item: keyof ResponsiveMap) => breakpoint && breakpoint.indexOf(item) !== -1) as any;
+        const matchBpt: Array<keyof ResponsiveMap> = (Object.keys(responsiveMap) as (keyof ResponsiveMap)[]).filter((item) => breakpoint && breakpoint.indexOf(item) !== -1) as any;
         const unRegisters = matchBpt.map(screen => registerMediaQuery(responsiveMap[screen], {
             match: () => {
                 this.responsiveHandler(screen, true);
@@ -113,4 +113,4 @@ class Sider extends React.PureComponent<SiderProps> {
     }
 }
 
-export default Sider;
+export default Sider;

+ 5 - 5
packages/semi-ui/locale/localeConsumer.tsx

@@ -7,13 +7,13 @@ import ConfigContext from '../configProvider/context';
 import DefaultLocale from './source/zh_CN';
 import { Locale } from './interface';
 
-type ChildrenRender = (componentLocal: Locale[keyof Locale], localeCode: string, dateFnsLocale: dateFns) => React.ReactNode;
-export interface LocaleConsumerProps {
+type ChildrenRender<T> = (componentLocal: T, localeCode: string, dateFnsLocale: dateFns) => React.ReactNode;
+export interface LocaleConsumerProps<T> {
     componentName: string;
-    children?: ChildrenRender;
+    children?: ChildrenRender<T>;
 }
 
-export default class LocaleConsumer extends Component<LocaleConsumerProps> {
+export default class LocaleConsumer<T> extends Component<LocaleConsumerProps<T>> {
     static propTypes = {
         componentName: PropTypes.string.isRequired,
         children: PropTypes.any,
@@ -23,7 +23,7 @@ export default class LocaleConsumer extends Component<LocaleConsumerProps> {
         componentName: '',
     };
 
-    renderChildren(localeData: Locale, children: ChildrenRender) {
+    renderChildren(localeData: Locale, children: ChildrenRender<T>) {
         const { componentName } = this.props;
         let locale = localeData;
         if (!localeData?.code) {

+ 8 - 3
packages/semi-ui/modal/useModal/HookModal.tsx

@@ -4,14 +4,19 @@ import { get } from 'lodash-es';
 import { ConfirmProps } from '../confirm';
 import { Motion } from '../../_base/base';
 
-interface HookModalProps{
+interface HookModalProps {
     afterClose: (...args: any[]) => void;
     config: ConfirmProps;
     motion?: Motion;
 }
 
+export interface HookModalRef {
+    destroy: () => void;
+    update: (newConfig: ConfirmProps) => void
+}
+
 // eslint-disable-next-line max-len
-const HookModal = ({ afterClose, config, ...props }: PropsWithChildren<HookModalProps>, ref: React.RefObject<{ destroy: () => void; update: (newConfig: ConfirmProps) => void }>) => {
+const HookModal = ({ afterClose, config, ...props }: PropsWithChildren<HookModalProps>, ref: React.Ref<any>) => {
     const [innerConfig, setInnerConfig] = React.useState(config);
 
     React.useImperativeHandle(ref, () => ({
@@ -54,4 +59,4 @@ const HookModal = ({ afterClose, config, ...props }: PropsWithChildren<HookModal
     );
 };
 
-export default React.forwardRef(HookModal);
+export default React.forwardRef<HookModalRef, HookModalProps>(HookModal);

+ 4 - 6
packages/semi-ui/modal/useModal/index.tsx

@@ -1,9 +1,10 @@
 import React, { ReactNode } from 'react';
-import HookModal from './HookModal';
-import { withConfirm, withInfo, withSuccess, withError, withWarning, ConfirmProps } from '../confirm';
+import HookModal, { HookModalRef } from './HookModal';
+import { ConfirmProps, withConfirm, withError, withInfo, withSuccess, withWarning } from '../confirm';
 import { ModalReactProps } from '../Modal';
 
 let uuid = 0;
+
 function usePatchElement(): ([ReactNode[], (element: ReactNode) => () => void]) {
     const [elements, setElements] = React.useState<ReactNode[]>([]);
 
@@ -26,10 +27,7 @@ export default function useModal() {
         return function hookConfirm(config: ModalReactProps) {
             uuid += 1;
 
-            const modalRef = React.createRef<{
-                destroy: () => void;
-                update: (newConfig: ConfirmProps) => void;
-            }>();
+            const modalRef = React.createRef<HookModalRef>();
 
             // eslint-disable-next-line prefer-const
             let closeFunc: () => void;

+ 2 - 2
packages/semi-ui/notification/index.tsx

@@ -177,8 +177,8 @@ class NotificationList extends BaseComponent<NotificationListProps, Notification
 
     add = (noticeOpts: NoticeProps) => this.foundation.addNotice(noticeOpts);
 
-    remove = (id: string) => {
-        this.foundation.removeNotice(id);
+    remove = (id: string | number) => {
+        this.foundation.removeNotice(String(id));
     };
 
     destroyAll = () => this.foundation.destroyAll();

+ 1 - 0
packages/semi-ui/package.json

@@ -24,6 +24,7 @@
         "@douyinfe/semi-icons": "2.1.0-beta.1",
         "@douyinfe/semi-illustrations": "2.1.0-beta.1",
         "@douyinfe/semi-theme-default": "2.1.0-beta.1",
+        "@types/react-window": "^1.8.2",
         "async-validator": "^3.5.0",
         "classnames": "^2.2.6",
         "copy-text-to-clipboard": "^2.1.1",

+ 1 - 1
packages/semi-ui/rating/index.tsx

@@ -30,7 +30,7 @@ export interface RatingProps {
     onFocus?: (e: React.FocusEvent) => void;
     onBlur?: (e: React.FocusEvent) => void;
     onKeyDown?: (e: React.KeyboardEvent) => void;
-    onClick?: (e: React.MouseEvent, index: number) => void;
+    onClick?: (e: React.MouseEvent | React.KeyboardEvent, index: number) => void;
     autoFocus?: boolean;
     size?: 'small' | 'default' | number;
     tooltips?: string[];

+ 1 - 0
packages/semi-ui/resizeObserver/index.tsx

@@ -55,6 +55,7 @@ export default class ReactResizeObserver extends BaseComponent<ReactResizeObserv
             // using findDOMNode for two reasons:
             // 1. cloning to insert a ref is unwieldy and not performant.
             // 2. ensure that we resolve to an actual DOM node (instead of any JSX ref instance).
+            // eslint-disable-next-line
             return findDOMNode(this.childNode || this);
         } catch (error) {
             // swallow error if findDOMNode is run on unmounted component.

+ 21 - 19
packages/semi-ui/scrollList/scrollItem.tsx

@@ -14,12 +14,13 @@ const msPerFrame = 1000 / 60;
 const blankReg = /^\s*$/;
 const wheelMode = 'wheel';
 
-export interface ScrollItemProps {
+type DebounceSelectFn = (e: React.UIEvent, newSelectedNode: HTMLElement) => void;
+export interface ScrollItemProps<T extends Item> {
     mode?: string;
     cycled?: boolean;
-    list?: Item[];
+    list?: T[];
     selectedIndex?: number;
-    onSelect?: (data: Item) => void;
+    onSelect?: (data: T) => void;
     transform?: (value: any, text: string) => string;
     className?: string;
     motion?: Motion;
@@ -31,8 +32,7 @@ export interface ScrollItemState {
     prependCount: number;
     appendCount: number;
 }
-
-export default class ScrollItem extends BaseComponent<ScrollItemProps, ScrollItemState> {
+export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItemProps<T>, ScrollItemState> {
     static propTypes = {
         mode: PropTypes.string,
         cycled: PropTypes.bool,
@@ -50,7 +50,7 @@ export default class ScrollItem extends BaseComponent<ScrollItemProps, ScrollIte
         selectedIndex: 0,
         motion: true,
         // transform: identity,
-        list: [] as Item[],
+        list: [] as const,
         onSelect: noop,
         cycled: false,
         mode: wheelMode,
@@ -63,15 +63,8 @@ export default class ScrollItem extends BaseComponent<ScrollItemProps, ScrollIte
     selector: unknown;
     scrollAnimation: any;
     scrolling: boolean;
-
-    throttledAdjustList = throttle((e, nearestNode) => {
-        this.foundation.adjustInfiniteList(this.list, this.wrapper, nearestNode);
-    }, msPerFrame);
-
-    debouncedSelect = debounce((e, nearestNode) => {
-        this._cacheSelectedNode(nearestNode);
-        this.foundation.selectNode(nearestNode, this.list);
-    }, msPerFrame * 5);
+    throttledAdjustList: DebounceSelectFn;
+    debouncedSelect: DebounceSelectFn;
 
     constructor(props = {}) {
         super(props);
@@ -93,10 +86,19 @@ export default class ScrollItem extends BaseComponent<ScrollItemProps, ScrollIte
 
         // cache if select action comes from outside
 
-        this.foundation = new ItemFoundation(this.adapter);
+        this.foundation = new ItemFoundation<ScrollItemProps<T>, ScrollItemState, T>(this.adapter);
+
+        this.throttledAdjustList = throttle((e, nearestNode) => {
+            this.foundation.adjustInfiniteList(this.list, this.wrapper, nearestNode);
+        }, msPerFrame);
+
+        this.debouncedSelect = debounce((e, nearestNode) => {
+            this._cacheSelectedNode(nearestNode);
+            this.foundation.selectNode(nearestNode, this.list);
+        }, msPerFrame * 5);
     }
 
-    get adapter(): ScrollItemAdapter<ScrollItemProps, ScrollItemState> {
+    get adapter(): ScrollItemAdapter<ScrollItemProps<T>, ScrollItemState, T> {
         return {
             ...super.adapter,
             setState: (states, callback) => this.setState({ ...states }, callback),
@@ -133,7 +135,7 @@ export default class ScrollItem extends BaseComponent<ScrollItemProps, ScrollIte
         }
     }
 
-    componentDidUpdate(prevProps: ScrollItemProps) {
+    componentDidUpdate(prevProps: ScrollItemProps<T>) {
         const { selectedIndex } = this.props;
 
         // smooth scroll to selected option
@@ -262,7 +264,7 @@ export default class ScrollItem extends BaseComponent<ScrollItemProps, ScrollIte
         return false;
     };
 
-    isDisabledData = (data: Item) => data && typeof data === 'object' && data.disabled;
+    isDisabledData = (data: T) => data && typeof data === 'object' && data.disabled;
 
     isWheelMode = () => this.props.mode === wheelMode;
 

+ 3 - 3
packages/semi-ui/select/index.tsx

@@ -11,7 +11,7 @@ import BaseComponent, { ValidateStatus } from '../_base/baseComponent';
 import { isEqual, isString, noop, get, isNumber } from 'lodash-es';
 import Tag from '../tag/index';
 import TagGroup from '../tag/group';
-import LocaleCosumer from '../locale/localeConsumer';
+import LocaleConsumer from '../locale/localeConsumer';
 import Popover from '../popover/index';
 import { numbers as popoverNumbers } from '@douyinfe/semi-foundation/popover/constants';
 import { FixedSizeList as List } from 'react-window';
@@ -689,14 +689,14 @@ class Select extends BaseComponent<SelectProps, SelectState> {
                     focused={isFocused}
                     style={style}
                 >
-                    <LocaleCosumer componentName="Select">
+                    <LocaleConsumer<Locale['Select']> componentName="Select" >
                         {(locale: Locale['Select']) => (
                             <>
                                 <span className={`${prefixcls}-create-tips`}>{locale.createText}</span>
                                 {option.value}
                             </>
                         )}
-                    </LocaleCosumer>
+                    </LocaleConsumer>
                 </Option>
             );
             return defaultCreateItem;

+ 3 - 3
packages/semi-ui/select/option.tsx

@@ -4,7 +4,7 @@ import classNames from 'classnames';
 import PropTypes from 'prop-types';
 import { isString } from 'lodash-es';
 import { cssClasses } from '@douyinfe/semi-foundation/select/constants';
-import LocaleCosumer from '../locale/localeConsumer';
+import LocaleConsumer from '../locale/localeConsumer';
 import { IconTick } from '@douyinfe/semi-icons';
 import { getHighLightTextHTML } from '../_utils/index';
 import { Locale } from '../locale/interface';
@@ -104,9 +104,9 @@ class Option extends PureComponent<OptionProps> {
                 return null;
             }
             return (
-                <LocaleCosumer componentName="Select">
+                <LocaleConsumer<Locale['Select']> componentName="Select">
                     {(locale: Locale['Select']) => <div className={optionClassName}>{emptyContent || locale.emptyText}</div>}
-                </LocaleCosumer>
+                </LocaleConsumer>
             );
         }
 

+ 3 - 1
packages/semi-ui/select/utils.tsx

@@ -33,7 +33,9 @@ const getOptionsFromGroup = (selectChildren: React.ReactNode) => {
 
     // avoid null
     // eslint-disable-next-line max-len
-    const childNodes = React.Children.toArray(selectChildren).filter((childNode: React.ReactElement) => childNode && childNode.props);
+    let childNodes = React.Children.toArray(selectChildren) as React.ReactElement[];
+    childNodes = childNodes.filter((childNode) => childNode && childNode.props);    
+
     let type = '';
     let optionIndex = -1;
 

+ 2 - 2
packages/semi-ui/sideSheet/SideSheetContent.tsx

@@ -11,7 +11,7 @@ const prefixCls = cssClasses.PREFIX;
 
 
 export interface SideSheetContentProps{
-    onClose?: (e: React.MouseEvent | MouseEvent) => void;
+    onClose?: (e: React.MouseEvent) => void;
     mask?: boolean;
     maskStyle?: CSSProperties;
     maskClosable?: boolean;
@@ -171,4 +171,4 @@ export default class SideSheetContent extends React.PureComponent<SideSheetConte
             </div>
         );
     }
-}
+}

+ 4 - 4
packages/semi-ui/sideSheet/index.tsx

@@ -31,7 +31,7 @@ export interface SideSheetReactProps extends SideSheetProps{
     title?: React.ReactNode;
     footer?: React.ReactNode;
     children?: React.ReactNode;
-    onCancel?: (e: React.MouseEvent) => void;
+    onCancel?: (e: React.MouseEvent | React.KeyboardEvent) => void;
 
 }
 
@@ -107,7 +107,7 @@ export default class SideSheet extends BaseComponent<SideSheetReactProps, SideSh
                     document.body.style.overflow = '';
                 }
             },
-            notifyCancel: (e: React.MouseEvent) => {
+            notifyCancel: (e: React.MouseEvent | React.KeyboardEvent) => {
                 this.props.onCancel && this.props.onCancel(e);
             },
             notifyVisibleChange: (visible: boolean) => {
@@ -169,11 +169,11 @@ export default class SideSheet extends BaseComponent<SideSheetReactProps, SideSh
         }
     }
 
-    handleCancel = (e: MouseEvent) => {
+    handleCancel = (e: React.MouseEvent) => {
         this.foundation.handleCancel(e);
     };
 
-    handleKeyDown = (e: MouseEvent) => {
+    handleKeyDown = (e: KeyboardEvent) => {
         this.foundation.handleKeyDown(e);
     };
 

+ 2 - 2
packages/semi-ui/slider/index.tsx

@@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
 import cls from 'classnames';
 import { cssClasses } from '@douyinfe/semi-foundation/slider/constants';
 import BaseComponent from '../_base/baseComponent';
-import SliderFoundation, { SliderAdapter, SliderProps as BasicSliceProps, SliderState } from '@douyinfe/semi-foundation/slider/foundation';
+import SliderFoundation, { SliderAdapter, SliderProps as BasicSliceProps, SliderState, tipFormatterBasicType } from '@douyinfe/semi-foundation/slider/foundation';
 import Tooltip from '../tooltip/index';
 import '@douyinfe/semi-foundation/slider/slider.scss';
 import { isEqual, noop } from 'lodash-es';
@@ -61,7 +61,7 @@ export default class Slider extends BaseComponent<SliderProps, SliderState> {
         min: 0,
         range: false, // Whether both sides
         step: 1,
-        tipFormatter: (value: number) => value,
+        tipFormatter: (value: tipFormatterBasicType | tipFormatterBasicType[]) => value,
         vertical: false,
         showBoundary: false,
         onAfterChange: (value: number | number[]) => {

+ 2 - 2
packages/semi-ui/steps/basicSteps.tsx

@@ -1,4 +1,4 @@
-import React, { cloneElement, Children, useMemo } from 'react';
+import React, { cloneElement, Children, useMemo, isValidElement, ReactElement } from 'react';
 import PropTypes from 'prop-types';
 import cls from 'classnames';
 import { stepsClasses as css } from '@douyinfe/semi-foundation/steps/constants';
@@ -35,7 +35,7 @@ const Steps = (props: BasicStepsProps) => {
         onChange,
     } = props;
     const inner = useMemo(() => {
-        const filteredChildren = Children.toArray(children).filter(c => Boolean(c));
+        const filteredChildren = Children.toArray(children).filter(c => isValidElement(c)) as Array<ReactElement>;
         const content = Children.map(filteredChildren, (child: React.ReactElement, index) => {
             if (!child) {
                 return null;

+ 4 - 4
packages/semi-ui/steps/fillSteps.tsx

@@ -1,4 +1,4 @@
-import React, { cloneElement, Children, useMemo } from 'react';
+import React, { cloneElement, Children, useMemo, ReactElement, isValidElement } from 'react';
 import PropTypes from 'prop-types';
 import cls from 'classnames';
 import { stepsClasses as css } from '@douyinfe/semi-foundation/steps/constants';
@@ -21,9 +21,9 @@ export interface FillStepsProps {
 const Steps = (props: FillStepsProps) => {
     const { current, status, children, prefixCls, initial, direction, className, style, onChange } = props;
     const inner = useMemo(() => {
-        const filteredChildren = Children.toArray(children).filter(c => Boolean(c));
+        const filteredChildren = Children.toArray(children).filter(c => isValidElement(c)) as Array<ReactElement>;
         const colStyle = direction === 'vertical' ? null : { width: `${100 / filteredChildren.length }%` };
-        const content = Children.map(filteredChildren, (child: React.ReactElement, index) => {
+        const content = Children.map(filteredChildren, (child: ReactElement, index) => {
             if (!child) {
                 return null;
             }
@@ -55,7 +55,7 @@ const Steps = (props: FillStepsProps) => {
             return <Col style={colStyle}>{cloneElement(child, { ...childProps })}</Col>;
         });
         return content;
-    }, [children, initial, prefixCls, direction, status, current]);
+    }, [children, initial, prefixCls, direction, status, current, onChange]);
 
     const wrapperCls = cls(className, {
         [prefixCls]: true,

+ 2 - 2
packages/semi-ui/steps/navSteps.tsx

@@ -1,4 +1,4 @@
-import React, { cloneElement, Children, useMemo } from 'react';
+import React, { cloneElement, Children, useMemo, isValidElement, ReactElement } from 'react';
 import PropTypes from 'prop-types';
 import cls from 'classnames';
 import { stepsClasses as css } from '@douyinfe/semi-foundation/steps/constants';
@@ -18,7 +18,7 @@ export interface NavStepsProps {
 const Steps = (props: NavStepsProps) => {
     const { size, current, initial, children, prefixCls, className, style, onChange } = props;
     const inner = useMemo(() => {
-        const filteredChildren = Children.toArray(children).filter(c => Boolean(c));
+        const filteredChildren = Children.toArray(children).filter(c => isValidElement(c)) as Array<ReactElement>;
         const total = filteredChildren.length;
         const content = Children.map(filteredChildren, (child: React.ReactElement, index) => {
             if (!child) {

+ 5 - 5
packages/semi-ui/table/Body/index.tsx

@@ -337,7 +337,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
     };
 
     // virtualized List innerElementType
-    renderTbody = React.forwardRef<HTMLDivElement, any>((props: any = {}, ref: React.MutableRefObject<HTMLDivElement>) => (
+    renderTbody = React.forwardRef<HTMLDivElement, any>((props: any = {}, ref: React.MutableRefObject<HTMLDivElement> | ((instance: HTMLDivElement) => void)) => (
         <div
             {...props}
             onScroll={(...args) => {
@@ -353,7 +353,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
     ));
 
     // virtualized List outerElementType
-    renderOuter = React.forwardRef<HTMLDivElement, any>((props: any, ref: React.MutableRefObject<HTMLDivElement>) => {
+    renderOuter = React.forwardRef<HTMLDivElement, any>((props: any, ref: React.MutableRefObject<HTMLDivElement> | ((instance: HTMLDivElement) => void)) => {
         const { children, ...rest } = props;
         // eslint-disable-next-line react/no-this-in-sfc
         const { handleWheel, prefixCls, emptySlot, dataSource } = this.props;
@@ -395,7 +395,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
         }
     };
 
-    renderVirtualizedBody = (direction: Direction) => {
+    renderVirtualizedBody = (direction?: Direction) => {
         const { scroll, prefixCls, virtualized, anyColumnFixed, columns } = this.props;
         const { virtualizedData } = this.state;
         const { getCellWidths } = this.context;
@@ -713,7 +713,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
         return renderedRows;
     }
 
-    renderBody = (direction: Direction) => {
+    renderBody = (direction?: Direction) => {
         const {
             scroll,
             prefixCls,
@@ -807,7 +807,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
         const { virtualized } = this.props;
         return (
             <ConfigContext.Consumer>
-                {({ direction }: { direction: Direction }) => (virtualized ? this.renderVirtualizedBody(direction) : this.renderBody(direction))}
+                {({ direction }: { direction?: Direction }) => (virtualized ? this.renderVirtualizedBody(direction) : this.renderBody(direction))}
             </ConfigContext.Consumer>
         );
     }

+ 1 - 1
packages/semi-ui/table/ResizableTable.tsx

@@ -16,7 +16,7 @@ import getColumns from './getColumns';
 import ResizableHeaderCell from './ResizableHeaderCell';
 import { TableProps, ColumnProps } from './interface';
 
-const ResizableTable = (props: TableProps = {}, ref: React.MutableRefObject<Table<any>>) => {
+const ResizableTable = (props: TableProps = {}, ref: React.MutableRefObject<Table<any>> | ((instance: Table<any>) => void)) => {
     const { components: propComponents, columns: propColumns, resizable, ...restProps } = props;
 
     const childrenColumnName = 'children';

+ 1 - 1
packages/semi-ui/tabs/TabBar.tsx

@@ -194,7 +194,7 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
         );
     };
 
-    renderOverflow = (items: [Array<OverflowItem>, Array<OverflowItem>]): Array<ReactNode> => items.map((item, ind) => {
+    renderOverflow = (items: any[]): Array<ReactNode> => items.map((item, ind) => {
         const icon = ind === 0 ? <IconChevronLeft /> : <IconChevronRight />;
         const pos = ind === 0 ? 'start' : 'end';
         return this.renderCollapse(item, icon, pos);

+ 11 - 10
packages/semi-ui/tabs/index.tsx

@@ -1,4 +1,5 @@
-import React, { createRef, MouseEvent, ReactElement, ReactNode, RefCallback, RefObject } from 'react';
+
+import React, { createRef, MouseEvent, ReactElement, ReactNode, RefCallback, RefObject, isValidElement } from 'react';
 import cls from 'classnames';
 import PropTypes from 'prop-types';
 import { cssClasses, strings } from '@douyinfe/semi-foundation/tabs/constants';
@@ -12,7 +13,7 @@ import '@douyinfe/semi-foundation/tabs/tabs.scss';
 import TabBar from './TabBar';
 import TabPane from './TabPane';
 import TabsContext from './tabs-context';
-import { PlainTab, TabPaneProps, TabsProps } from './interface';
+import { TabsProps, PlainTab, TabBarProps } from './interface';
 
 const panePickKeys = Object.keys(omit(TabPane.propTypes, ['children']));
 
@@ -137,7 +138,7 @@ class Tabs extends BaseComponent<TabsProps, TabsState> {
             getDefaultActiveKeyFromChildren: (): string => {
                 const { tabList, children } = this.props;
                 let activeKey = '';
-                const list = tabList ? tabList : React.Children.toArray(children).map((child: ReactElement<TabPaneProps>) => child.props);
+                const list = tabList ? tabList : React.Children.toArray(children).map((child) => isValidElement(child) ? child.props : null);
                 list.forEach(item => {
                     if (item && !activeKey && !item.disabled) {
                         activeKey = item.itemKey;
@@ -161,11 +162,11 @@ class Tabs extends BaseComponent<TabsProps, TabsState> {
 
     componentDidUpdate(prevProps: TabsProps): void {
         // Panes state acts on tab bar, no need to compare TabPane children
-        const prevChildrenProps = React.Children.toArray(prevProps.children).map((child: ReactElement<TabPaneProps>) =>
-            pick(child.props, panePickKeys)
+        const prevChildrenProps = React.Children.toArray(prevProps.children).map((child) =>
+            pick(isValidElement(child) ? child.props : null, panePickKeys)
         );
-        const nowChildrenProps = React.Children.toArray(this.props.children).map((child: ReactElement<TabPaneProps>) =>
-            pick(child.props, panePickKeys)
+        const nowChildrenProps = React.Children.toArray(this.props.children).map((child) =>
+            pick(isValidElement(child) ? child.props : null, panePickKeys)
         );
 
         const isTabListType = this.props.tabList || prevProps.tabList;
@@ -210,8 +211,8 @@ class Tabs extends BaseComponent<TabsProps, TabsState> {
         if (tabList || !Array.isArray(children)) {
             return children;
         }
-        return React.Children.toArray(children).filter((pane: ReactElement) => {
-            if (pane && pane.type && (pane.type as any).isTabPane) {
+        return React.Children.toArray(children).filter((pane) => {
+            if (isValidElement(pane) && pane.type && (pane.type as any).isTabPane) {
                 return pane.props.itemKey === activeKey;
             }
             return true;
@@ -265,7 +266,7 @@ class Tabs extends BaseComponent<TabsProps, TabsState> {
             tabPosition,
             type,
             deleteTabItem: this.deleteTabItem
-        };
+        } as TabBarProps;
 
         const tabBar = renderTabBar ? renderTabBar(tabBarProps, TabBar) : <TabBar {...tabBarProps} />;
         const content = keepDOM ? children : this.getActiveItem();

+ 12 - 7
packages/semi-ui/timePicker/Combobox.tsx

@@ -42,6 +42,11 @@ export interface ComboboxState {
     secondOptions: number[];
 }
 
+export type FormatOptionReturn = ReturnType<typeof formatOption>;
+export interface AMPMOptionItem {
+    value: string;
+    text: string;
+}
 
 class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
     static propTypes = {
@@ -97,7 +102,7 @@ class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
         // this.foundation.init();
     }
 
-    cacheRefCurrent = (key: string, current: ScrollItem) => {
+    cacheRefCurrent = (key: string, current: ScrollItem<FormatOptionReturn> | ScrollItem<AMPMOptionItem>) => {
         if (key && typeof key === 'string') {
             this.adapter.setCache(key, current);
         }
@@ -115,7 +120,7 @@ class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
         });
     };
 
-    onItemChange = ({ type, value }: { type: string; value: string }) => {
+    onItemChange = ({ type, value, disabled }: { type?: string; value: string; disabled?: boolean; }) => {
         // eslint-disable-next-line prefer-const
         let { onChange, use12Hours, isAM, format, timeStampValue } = this.props;
         const transformValue = this.foundation.getDisplayDateFromTimeStamp(timeStampValue);
@@ -188,7 +193,7 @@ class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
         const className = `${prefixCls}-list-hour`;
 
         return (
-            <ScrollItem
+            <ScrollItem<FormatOptionReturn>
                 ref={current => this.cacheRefCurrent('hour', current)}
                 mode={'wheel'}
                 transform={transformHour}
@@ -219,7 +224,7 @@ class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
         const transformMinute = (min: string) => min + locale.minute;
 
         return (
-            <ScrollItem
+            <ScrollItem<FormatOptionReturn>
                 ref={current => this.cacheRefCurrent('minute', current)}
                 mode={'wheel'}
                 transform={transformMinute}
@@ -251,7 +256,7 @@ class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
         const transformSecond = (sec: number) => String(sec) + locale.second;
 
         return (
-            <ScrollItem
+            <ScrollItem<FormatOptionReturn>
                 ref={current => this.cacheRefCurrent('second', current)}
                 mode={'wheel'}
                 transform={transformSecond}
@@ -272,7 +277,7 @@ class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
             return null;
         }
 
-        const AMPMOptions = [
+        const AMPMOptions: AMPMOptionItem[] = [
             {
                 value: 'AM',
                 text: locale.AM || '上午',
@@ -288,7 +293,7 @@ class Combobox extends BaseComponent<ComboboxProps, ComboboxState> {
         const className = `${prefixCls}-list-ampm`;
 
         return (
-            <ScrollItem
+            <ScrollItem<AMPMOptionItem>
                 ref={current => this.cacheRefCurrent('ampm', current)}
                 mode={'wheel'}
                 className={className}

+ 1 - 1
packages/semi-ui/timePicker/TimePicker.tsx

@@ -70,7 +70,7 @@ export type TimePickerProps = {
     position?: Position;
     prefixCls?: string;
     rangeSeparator?: string;
-    scrollItemProps?: ScrollItemProps;
+    scrollItemProps?: ScrollItemProps<any>;
     secondStep?: number;
     showClear?: boolean;
     size?: InputSize;

+ 1 - 1
packages/semi-ui/timePicker/index.tsx

@@ -26,7 +26,7 @@ export default class LocaleTimePicker extends React.PureComponent<LocalePickerPr
         const { type } = this.props;
         return (
             <ConfigContext.Consumer>
-                {({ timeZone }: { timeZone: string | number }) => (
+                {({ timeZone }: { timeZone?: string | number }) => (
                     <LocaleConsumer componentName="TimePicker">
                         {(locale: Locale['TimePicker'], localeCode: string, dateFnsLocale: Locale['dateFnsLocale']) => (
                             <BaseTimePicker

+ 2 - 1
packages/semi-ui/treeSelect/index.tsx

@@ -488,6 +488,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
                 const clickOutsideHandler = (e: Event) => {
                     const optionInstance = this.optionsRef && this.optionsRef.current as React.ReactInstance;
                     const triggerDom = this.triggerRef && this.triggerRef.current;
+                    // eslint-disable-next-line
                     const optionsDom = ReactDOM.findDOMNode(optionInstance);
                     const target = e.target as Element;
                     if (
@@ -935,7 +936,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
         const nodeHaveData = !isEmpty(nodes) && !isEmpty(nodes[0]);
         const isDisableStrictlyNode = disableStrictly && nodeHaveData && disabledKeys.has(nodes[0].key);
         const closable = nodeHaveData && !nodes[0].disabled && !disabled && !isDisableStrictlyNode;
-        const onClose = (tagChildren: string, e: React.MouseEvent) => {
+        const onClose = (tagChildren: React.ReactNode, e: React.MouseEvent) => {
             // When value has not changed, prevent clicking tag closeBtn to close tag
             e.preventDefault();
             this.removeTag(key);

+ 2 - 2
packages/semi-ui/tsconfig.json

@@ -22,10 +22,10 @@
         "experimentalDecorators": true,
         "noImplicitReturns": true,
         "noImplicitThis": false,
-        "strictNullChecks": false,
         "esModuleInterop": true,
         "skipLibCheck": true,
-        "declaration": true
+        "declaration": true,
+        "strictNullChecks": false
     },
     "include": ["**/*.tsx", "**/*.ts"],
     "exclude": ["node_modules", "packages/rollup-plugin-semi-svg"]

+ 3 - 17
packages/semi-ui/upload/fileCard.tsx

@@ -3,6 +3,7 @@ import cls from 'classnames';
 import PropTypes from 'prop-types';
 import { cssClasses, strings } from '@douyinfe/semi-foundation/upload/constants';
 import { getFileSize } from '@douyinfe/semi-foundation/upload/utils';
+import { BaseFileItem } from '@douyinfe/semi-foundation/upload/foundation';
 import LocaleConsumer from '../locale/localeConsumer';
 import { Locale } from '../locale/interface';
 
@@ -11,6 +12,7 @@ import Progress from '../progress/index';
 import Tooltip from '../tooltip/index';
 import Spin from '../spin/index';
 import { isElement } from '../_base/reactUtils';
+import { RenderFileItemProps } from './interface';
 import { IconAlertCircle, IconClose, IconFile, IconRefresh } from '@douyinfe/semi-icons';
 
 const prefixCls = cssClasses.PREFIX;
@@ -41,25 +43,9 @@ const DirectorySvg: FC<SVGProps<SVGSVGElement>> = (props = {}) => (
 
 );
 
-export interface FileCardProps {
+export interface FileCardProps extends RenderFileItemProps {
     className?: string;
-    disabled?: boolean;
-    listType?: 'picture' | 'list';
-    name?: string;
-    onPreviewClick?: MouseEventHandler<HTMLDivElement>;
-    onRemove?: (props: FileCardProps, e: MouseEvent) => void;
-    onReplace?: (props: FileCardProps, e: MouseEvent) => void;
-    onRetry?: (props: FileCardProps, e: MouseEvent) => void;
-    percent?: number;
-    preview?: boolean;
-    previewFile?: (props: FileCardProps) => ReactNode;
-    showReplace?: boolean;
-    showRetry?: boolean;
-    size?: string;
-    status?: string;
     style?: CSSProperties;
-    url?: string;
-    validateMessage?: ReactNode;
 }
 
 

+ 3 - 57
packages/semi-ui/upload/index.tsx

@@ -9,67 +9,13 @@ import FileCard from './fileCard';
 import BaseComponent, { ValidateStatus } from '../_base/baseComponent';
 import LocaleConsumer from '../locale/localeConsumer';
 import { IconUpload } from '@douyinfe/semi-icons';
-import { ArrayElement } from '../_base/base';
+import { FileItem, RenderFileItemProps, UploadListType, PromptPositionType, BeforeUploadProps, AfterUploadProps, OnChangeProps, customRequestArgs, CustomError } from './interface';
 import { Locale } from '../locale/interface';
 import '@douyinfe/semi-foundation/upload/upload.scss';
 
 const prefixCls = cssClasses.PREFIX;
 
-export { BeforeUploadObjectResult, AfterUploadResult };
-
-export interface FileItem extends BaseFileItem {
-    validateMessage?: ReactNode;
-}
-
-export type UploadListType = ArrayElement<typeof strings.LIST_TYPE>;
-export type PromptPositionType = ArrayElement<typeof strings.PROMPT_POSITION>;
-export interface RenderFileItemProps extends FileItem {
-    previewFile: (fileItem: FileItem) => ReactNode;
-    listType: UploadListType;
-    onRemove: () => void;
-    onRetry: () => void;
-    onReplace: () => void;
-    key: string;
-    showRetry: boolean;
-    showReplace: boolean;
-    style: CSSProperties;
-    disabled: boolean;
-    onPreviewClick: () => void;
-}
-
-export interface BeforeUploadProps {
-    file: FileItem;
-    fileList: Array<FileItem>;
-}
-
-export interface AfterUploadProps {
-    file: FileItem;
-    fileList: Array<FileItem>;
-    response: any;
-}
-
-export interface OnChangeProps {
-    fileList: Array<FileItem>;
-    currentFile: FileItem;
-}
-
-export interface customRequestArgs {
-    fileName: string; // Current file name
-    data: Record<string, any>; // User-set props.data
-    file: FileItem;
-    fileInstance: File; // Original File Object which extends to the blob, the file object actually acquired by the browser (https://developer.mozilla.org/zh-CN/docs/Web/API/File)
-    onProgress: (event: { total: number; loaded: number }) => any; // The function that should be called during the upload process, the event needs to contain the total and loaded attributes
-    onError: (userXhr: { status?: number }, e: Event) => any; // Functions to call in case of upload error
-    onSuccess: (response: any, e: Event) => any; // The function that should be called after the upload is successful, the response is the request result after the upload is successful
-    withCredentials: boolean; // User-set props.with Credentials
-    action: string; // User-set props.action
-}
-
-export interface CustomError extends Error {
-    status: number;
-    method: string;
-    url: string;
-}
+export { FileItem, RenderFileItemProps, UploadListType, PromptPositionType, BeforeUploadProps, AfterUploadProps, OnChangeProps, customRequestArgs, CustomError, BeforeUploadObjectResult, AfterUploadResult };
 
 export interface UploadProps {
     accept?: string;
@@ -114,7 +60,7 @@ export interface UploadProps {
     onRetry?: (fileItem: FileItem) => void;
     onSizeError?: (file: File, fileList: Array<FileItem>) => void;
     onSuccess?: (responseBody: any, file: File, fileList: Array<FileItem>) => void;
-    previewFile?: (fileItem: FileItem) => ReactNode;
+    previewFile?: (renderFileItemProps: RenderFileItemProps) => ReactNode;
     prompt?: ReactNode;
     promptPosition?: PromptPositionType;
     renderFileItem?: (renderFileItemProps: RenderFileItemProps) => ReactNode;

+ 59 - 0
packages/semi-ui/upload/interface.ts

@@ -0,0 +1,59 @@
+import { ReactNode, CSSProperties, MouseEvent } from 'react';
+import { BaseFileItem } from '@douyinfe/semi-foundation/upload/foundation';
+import { strings } from '@douyinfe/semi-foundation/upload/constants';
+import { ArrayElement } from '../_base/base';
+
+export type PromptPositionType = ArrayElement<typeof strings.PROMPT_POSITION>;
+export type UploadListType = ArrayElement<typeof strings.LIST_TYPE>;
+
+export interface BeforeUploadProps {
+    file: FileItem;
+    fileList: Array<FileItem>;
+}
+
+export interface AfterUploadProps {
+    file: FileItem;
+    fileList: Array<FileItem>;
+    response: any;
+}
+
+export interface OnChangeProps {
+    fileList: Array<FileItem>;
+    currentFile: FileItem;
+}
+
+export interface customRequestArgs {
+    fileName: string; // Current file name
+    data: Record<string, any>; // User-set props.data
+    file: FileItem;
+    fileInstance: File; // Original File Object which extends to the blob, the file object actually acquired by the browser (https://developer.mozilla.org/zh-CN/docs/Web/API/File)
+    onProgress: (event: { total: number; loaded: number }) => any; // The function that should be called during the upload process, the event needs to contain the total and loaded attributes
+    onError: (userXhr: { status?: number }, e: Event) => any; // Functions to call in case of upload error
+    onSuccess: (response: any, e: Event) => any; // The function that should be called after the upload is successful, the response is the request result after the upload is successful
+    withCredentials: boolean; // User-set props.with Credentials
+    action: string; // User-set props.action
+}
+
+export interface CustomError extends Error {
+    status: number;
+    method: string;
+    url: string;
+}
+
+export interface FileItem extends BaseFileItem {
+    validateMessage?: ReactNode;
+}
+
+export interface RenderFileItemProps extends FileItem {
+    previewFile?: (fileItem: RenderFileItemProps) => ReactNode;
+    listType: UploadListType;
+    onRemove: (props: RenderFileItemProps, e: MouseEvent) => void;
+    onRetry: (props: RenderFileItemProps, e: MouseEvent) => void;
+    onReplace: (props: RenderFileItemProps, e: MouseEvent) => void;
+    key: string;
+    showRetry: boolean;
+    showReplace: boolean;
+    style?: CSSProperties;
+    disabled: boolean;
+    onPreviewClick: () => void;
+}

+ 14 - 14
scripts/release.js

@@ -1,18 +1,18 @@
-const fs = require('fs')
-const _ = require('lodash')
+const fs = require('fs');
+const _ = require('lodash');
 const github = require('@actions/github');
 const { Octokit } = require('@octokit/rest');
 const core = require('@actions/core');
 const { info, error } = core;
 
-const pathArr = process.env.CHANGELOG_PATH.replace(/ /g, '').split(',')
+const pathArr = process.env.CHANGELOG_PATH.replace(/ /g, '').split(',');
 
 const { owner, repo } = github.context.repo;
 const { ref: version } = github.context.payload;
-const versionNo = version.substr(1) // 'v1.0.0' -> '1.0.0'
+const versionNo = version.substr(1); // 'v1.0.0' -> '1.0.0'
 
 const genVersionChangeLog = (path, targetVersion) => {
-    const changelogRaw = fs.readFileSync(path, 'utf-8')
+    const changelogRaw = fs.readFileSync(path, 'utf-8');
 
     const lines = changelogRaw.split('\n');
     let changeLogLines = [];
@@ -30,19 +30,19 @@ const genVersionChangeLog = (path, targetVersion) => {
             if (line.startsWith('####')) {
                 const versionReg = /.*((\d{1,2}\.){2}\d{1,2}(-\w+\.\d+)?)/;
                 let result = versionReg.exec(line);
-                begin = _.get(result, '1', '').trim().toLowerCase() === targetVersion
+                begin = _.get(result, '1', '').trim().toLowerCase() === targetVersion;
             }
         }
     }
-    return changeLogLines.join('\n')
-}
+    return changeLogLines.join('\n');
+};
 
 async function main() {
     try {
         const versionChangelog = pathArr.map((path) => {
-            let changelog = genVersionChangeLog(path, versionNo)
-            return changelog
-        }).join('\n---\n')
+            let changelog = genVersionChangeLog(path, versionNo);
+            return changelog;
+        }).join('\n---\n');
         const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
 
         await octokit.repos.createRelease({
@@ -53,10 +53,10 @@ async function main() {
             body: versionChangelog,
             prerelease: version.includes('beta'),
         });
-        info(`${version} released`)
+        info(`${version} released`);
     } catch (err) {
-        error(err)
+        error(err);
     }
 }
 
-main()
+main();

+ 0 - 1
tsconfig.json

@@ -25,7 +25,6 @@
         "noImplicitReturns": true,
         "noImplicitThis": false,
         "strictNullChecks": false,
-        // "noUnusedLocals": true,
         "esModuleInterop": true,
         "skipLibCheck": true,
     },