type: fix type errors of React.Key (#44938)

* type: fix .dumi typing error

* type: fix React.Key type error

* type: fix React.Key type error

* type: fix React.Key type error

* type: fix React.Key type error

* Apply suggestions from code review

Signed-off-by: afc163 <afc163@gmail.com>

* fix: test case

* fix: test case

* chore: use @types/react latest version

* Apply suggestions from code review

Signed-off-by: afc163 <afc163@gmail.com>

* chore: update form def

* chore: more ts

* chore: revert demo ts

* chore: bump ver

* chore: fix more

* chore: fix demo

* chore: back of ci

* chore: fix ts

* chore: fix ts

* chore: part of it

* chore: fix ts

* chore: bump ver

* chore: fix lint

* chore: fix

* test: update test

---------

Signed-off-by: afc163 <afc163@gmail.com>
Co-authored-by: 二货机器人 <smith3816@gmail.com>
This commit is contained in:
afc163 2023-09-20 11:01:49 +08:00 committed by GitHub
parent 89a646e64c
commit 5c99a5ee49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 57 additions and 47 deletions

View File

@ -19,12 +19,6 @@ interface NewToken {
contentMarginTop: number;
}
// 通过给 antd-style 扩展 CustomToken 对象类型定义,可以为 useTheme 中增加相应的 token 对象
declare module 'antd-style' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface CustomToken extends NewToken {}
}
const SiteThemeProvider: React.FC<ThemeProviderProps<any>> = ({ children, theme, ...rest }) => {
const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext);
const rootPrefixCls = getPrefixCls();

View File

@ -1,4 +1,5 @@
import * as React from 'react';
import useForceUpdate from './useForceUpdate';
type UseSyncStateProps<T> = readonly [() => T, (newValue: T) => void];

View File

@ -2,7 +2,7 @@ import * as React from 'react';
import classNames from 'classnames';
import { Field, FieldContext, ListContext } from 'rc-field-form';
import type { FieldProps } from 'rc-field-form/lib/Field';
import type { Meta } from 'rc-field-form/lib/interface';
import type { InternalNamePath, Meta } from 'rc-field-form/lib/interface';
import useState from 'rc-util/lib/hooks/useState';
import { supportRef } from 'rc-util/lib/ref';
@ -138,7 +138,7 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
// ========================= MISC =========================
// Get `noStyle` required info
const listContext = React.useContext(ListContext);
const fieldKeyPathRef = React.useRef<React.Key[]>();
const fieldKeyPathRef = React.useRef<InternalNamePath>();
// ======================== Errors ========================
// >>>>> Collect sub field errors

View File

@ -78884,7 +78884,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
tabindex="-1"
type="button"
>
آذر
سپتامبر
</button>
<button
class="ant-picker-year-btn"
@ -80943,7 +80943,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
tabindex="-1"
type="button"
>
آذر
سپتامبر
</button>
<button
class="ant-picker-year-btn"
@ -81481,7 +81481,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
tabindex="-1"
type="button"
>
دی
اکتبر
</button>
<button
class="ant-picker-year-btn"
@ -82578,9 +82578,9 @@ exports[`Locale Provider should display the text as fa 1`] = `
</span>
<span
class="ant-select-selection-item"
title="آذر"
title="سپتامبر"
>
آذر
سپتامبر
</span>
</div>
<span

View File

@ -1,10 +1,11 @@
/* eslint-disable no-unsafe-optional-chaining */
/* eslint-disable react/no-multi-comp */
import React, { useEffect, useState } from 'react';
import type { ColumnGroupType, ColumnType, TableProps } from '..';
import Table from '..';
import { act, fireEvent, render, waitFor } from '../../../tests/utils';
import { resetWarned } from '../../_util/warning';
import { act, fireEvent, render, waitFor } from '../../../tests/utils';
import Button from '../../button';
import ConfigProvider from '../../config-provider';
import Input from '../../input';

View File

@ -22,6 +22,7 @@ import Tree from '../../../tree';
import type {
ColumnFilterItem,
ColumnType,
FilterKey,
FilterSearchType,
FilterValue,
GetPopupContainer,
@ -31,7 +32,7 @@ import type {
import FilterSearch from './FilterSearch';
import FilterDropdownMenuWrapper from './FilterWrapper';
type FilterTreeDataNode = FieldDataNode<{ title: React.ReactNode; key: React.Key }>;
type FilterTreeDataNode = FieldDataNode<{ title: React.ReactNode; key: string }>;
interface FilterRestProps {
confirm?: Boolean;
@ -134,6 +135,10 @@ export interface FilterDropdownProps<RecordType> {
filterResetToDefaultFilteredValue?: boolean;
}
function wrapStringListType(keys?: FilterKey) {
return (keys as string[]) || [];
}
function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
const {
tablePrefixCls,
@ -196,20 +201,22 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
// ===================== Select Keys =====================
const propFilteredKeys = filterState?.filteredKeys;
const [getFilteredKeysSync, setFilteredKeysSync] = useSyncState(propFilteredKeys || []);
const [getFilteredKeysSync, setFilteredKeysSync] = useSyncState(
wrapStringListType(propFilteredKeys),
);
const onSelectKeys = ({ selectedKeys }: { selectedKeys: Key[] }) => {
const onSelectKeys = ({ selectedKeys }: { selectedKeys: string[] }) => {
setFilteredKeysSync(selectedKeys);
};
const onCheck = (
keys: Key[],
keys: string[],
{ node, checked }: { node: EventDataNode<FilterTreeDataNode>; checked: boolean },
) => {
if (!filterMultiple) {
onSelectKeys({ selectedKeys: checked && node.key ? [node.key] : [] });
} else {
onSelectKeys({ selectedKeys: keys as Key[] });
onSelectKeys({ selectedKeys: keys });
}
};
@ -217,7 +224,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
if (!visible) {
return;
}
onSelectKeys({ selectedKeys: propFilteredKeys || [] });
onSelectKeys({ selectedKeys: wrapStringListType(propFilteredKeys) });
}, [propFilteredKeys]);
// ====================== Open Keys ======================
@ -240,7 +247,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
}, [visible]);
// ======================= Submit ========================
const internalTriggerFilter = (keys?: Key[]) => {
const internalTriggerFilter = (keys?: string[]) => {
const mergedKeys = keys && keys.length ? keys : null;
if (mergedKeys === null && (!filterState || !filterState.filteredKeys)) {
return null;
@ -291,7 +298,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
const onVisibleChange = (newVisible: boolean) => {
if (newVisible && propFilteredKeys !== undefined) {
// Sync filteredKeys on appear in controlled mode (propFilteredKeys !== undefined)
setFilteredKeysSync(propFilteredKeys || []);
setFilteredKeysSync(wrapStringListType(propFilteredKeys));
}
triggerVisible(newVisible);
@ -321,7 +328,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
const key = String(filter.value);
const item: FilterTreeDataNode = {
title: filter.text,
key: filter.value !== undefined ? key : index,
key: filter.value !== undefined ? key : String(index),
};
if (filter.children) {
item.children = getTreeData({ filters: filter.children });
@ -340,7 +347,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
if (typeof column.filterDropdown === 'function') {
dropdownContent = column.filterDropdown({
prefixCls: `${dropdownPrefixCls}-custom`,
setSelectedKeys: (selectedKeys: Key[]) => onSelectKeys({ selectedKeys }),
setSelectedKeys: (selectedKeys: string[]) => onSelectKeys({ selectedKeys }),
selectedKeys: getFilteredKeysSync(),
confirm: doFilter,
clearFilters: onReset,
@ -439,7 +446,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
className={dropdownMenuClass}
onSelect={onSelectKeys}
onDeselect={onSelectKeys}
selectedKeys={selectedKeys as string[]}
selectedKeys={selectedKeys}
getPopupContainer={getPopupContainer}
openKeys={openKeys}
onOpenChange={onOpenChange}

View File

@ -9,6 +9,7 @@ import type {
FilterValue,
GetPopupContainer,
Key,
SafeKey,
TableLocale,
TransformColumns,
} from '../../interface';
@ -133,14 +134,17 @@ function generateFilterInfo<RecordType>(filterStates: FilterState<RecordType>[])
const currentFilters: Record<string, FilterValue | null> = {};
filterStates.forEach(({ key, filteredKeys, column }) => {
const keyAsString = key as SafeKey;
const { filters, filterDropdown } = column;
if (filterDropdown) {
currentFilters[key] = filteredKeys || null;
currentFilters[keyAsString] = filteredKeys || null;
} else if (Array.isArray(filteredKeys)) {
const keys = flattenKeys(filters);
currentFilters[key] = keys.filter((originKey) => filteredKeys.includes(String(originKey)));
currentFilters[keyAsString] = keys.filter((originKey) =>
filteredKeys.includes(String(originKey)),
);
} else {
currentFilters[key] = null;
currentFilters[keyAsString] = null;
}
});

View File

@ -1,3 +1,4 @@
import type * as React from 'react';
import type {
FixedType,
GetComponentProps,
@ -5,14 +6,14 @@ import type {
RenderedCell as RcRenderedCell,
} from 'rc-table/lib/interface';
import { ExpandableConfig, GetRowKey } from 'rc-table/lib/interface';
import type * as React from 'react';
import type { Breakpoint } from '../_util/responsiveObserver';
import type { AnyObject } from '../_util/type';
import type { CheckboxProps } from '../checkbox';
import type { PaginationProps } from '../pagination';
import type { TooltipProps } from '../tooltip';
import type { InternalTableProps, TableProps } from './InternalTable';
import type { INTERNAL_SELECTION_ITEM } from './hooks/useSelection';
import type { InternalTableProps, TableProps } from './InternalTable';
export type RefTable = <RecordType extends AnyObject = AnyObject>(
props: React.PropsWithChildren<TableProps<RecordType>> & { ref?: React.Ref<HTMLDivElement> },
@ -28,6 +29,8 @@ export { ExpandableConfig, GetRowKey };
export type Key = React.Key;
export type SafeKey = Exclude<Key, bigint>;
export type RowSelectionType = 'checkbox' | 'radio';
export type SelectionItemSelectFn = (currentRowKeys: Key[]) => void;
@ -57,13 +60,13 @@ export interface TableLocale {
export type SortOrder = 'descend' | 'ascend' | null;
const TableActions = ['paginate', 'sort', 'filter'] as const;
export type TableAction = (typeof TableActions)[number];
export type TableAction = typeof TableActions[number];
export type CompareFn<T> = (a: T, b: T, sortOrder?: SortOrder) => number;
export interface ColumnFilterItem {
text: React.ReactNode;
value: string | number | boolean;
value: React.Key | boolean;
children?: ColumnFilterItem[];
}
@ -82,7 +85,7 @@ export type ColumnTitle<RecordType> =
| ((props: ColumnTitleProps<RecordType>) => React.ReactNode);
export type FilterValue = (Key | boolean)[];
export type FilterKey = Key[] | null;
export type FilterKey = (string | number)[] | null;
export type FilterSearchType<RecordType = AnyObject> =
| boolean
| ((input: string, record: RecordType) => boolean);
@ -133,7 +136,7 @@ export interface ColumnType<RecordType> extends Omit<RcColumnType<RecordType>, '
filterIcon?: React.ReactNode | ((filtered: boolean) => React.ReactNode);
filterMode?: 'menu' | 'tree';
filterSearch?: FilterSearchType<ColumnFilterItem>;
onFilter?: (value: string | number | boolean, record: RecordType) => boolean;
onFilter?: (value: React.Key | boolean, record: RecordType) => boolean;
filterDropdownOpen?: boolean;
onFilterDropdownOpenChange?: (visible: boolean) => void;
filterResetToDefaultFilteredValue?: boolean;

View File

@ -10,7 +10,7 @@ interface TreeTransferProps {
}
// Customize Table Transfer
const isChecked = (selectedKeys: (string | number)[], eventKey: string | number) =>
const isChecked = (selectedKeys: React.Key[], eventKey: React.Key) =>
selectedKeys.includes(eventKey);
const generateTree = (treeNodes: DataNode[] = [], checkedKeys: string[] = []): DataNode[] =>

View File

@ -1,6 +1,6 @@
import debounce from 'lodash/debounce';
import type RcTree from 'rc-tree';
import type { Key } from 'react';
import type { Key } from 'rc-tree/lib/interface';
import React from 'react';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';

View File

@ -1,9 +1,9 @@
/* eslint-disable @typescript-eslint/no-shadow */
import { CarryOutOutlined } from '@ant-design/icons';
import type { DataNode } from 'rc-tree/lib/interface';
import React from 'react';
import { CarryOutOutlined } from '@ant-design/icons';
import type { TreeProps } from 'antd';
import { Switch, Tree } from 'antd';
import type { DataNode } from 'rc-tree/lib/interface';
const x = 3;
const y = 2;

View File

@ -79,8 +79,8 @@ const App: React.FC = () => {
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
setExpandedKeys(newExpandedKeys as React.Key[]);
.filter((item, i, self): item is React.Key => !!(item && self.indexOf(item) === i));
setExpandedKeys(newExpandedKeys);
setSearchValue(value);
setAutoExpandParent(true);
};

View File

@ -129,11 +129,11 @@
"rc-dialog": "~9.2.0",
"rc-drawer": "~6.4.1",
"rc-dropdown": "~4.1.0",
"rc-field-form": "~1.38.0",
"rc-field-form": "~1.38.1",
"rc-image": "~7.2.0",
"rc-input": "~1.1.1",
"rc-input-number": "~8.0.4",
"rc-mentions": "~2.7.0",
"rc-input": "~1.2.1",
"rc-input-number": "~8.1.0",
"rc-mentions": "~2.8.0",
"rc-menu": "~9.12.0",
"rc-motion": "^2.9.0",
"rc-notification": "~5.1.1",
@ -149,9 +149,9 @@
"rc-switch": "~4.1.0",
"rc-table": "~7.34.0",
"rc-tabs": "~12.12.1",
"rc-textarea": "~1.3.4",
"rc-textarea": "~1.4.0",
"rc-tooltip": "~6.0.1",
"rc-tree": "~5.7.10",
"rc-tree": "~5.7.12",
"rc-tree-select": "~5.12.1",
"rc-upload": "~4.3.4",
"rc-util": "^5.37.0",
@ -198,7 +198,7 @@
"@types/prismjs": "^1.26.0",
"@types/progress": "^2.0.5",
"@types/qs": "^6.9.7",
"@types/react": "18.2.1",
"@types/react": "^18.0.0",
"@types/react-copy-to-clipboard": "^5.0.0",
"@types/react-dom": "^18.0.0",
"@types/react-highlight-words": "^0.16.4",