type: params type support generic (#43211)

* type: type optimization

* test: add test case
This commit is contained in:
lijianan 2023-06-29 13:03:52 +08:00 committed by GitHub
parent 90a381df2a
commit 00f4ed3dc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 16 deletions

View File

@ -46,9 +46,9 @@ export type ItemType = Partial<BreadcrumbItemType & BreadcrumbSeparatorType>;
export type InternalRouteType = Partial<BreadcrumbItemType & BreadcrumbSeparatorType>; export type InternalRouteType = Partial<BreadcrumbItemType & BreadcrumbSeparatorType>;
export interface BreadcrumbProps { export interface BreadcrumbProps<T extends Record<PropertyKey, any> = any> {
prefixCls?: string; prefixCls?: string;
params?: any; params?: T;
separator?: React.ReactNode; separator?: React.ReactNode;
style?: React.CSSProperties; style?: React.CSSProperties;
className?: string; className?: string;
@ -60,19 +60,13 @@ export interface BreadcrumbProps {
items?: ItemType[]; items?: ItemType[];
itemRender?: ( itemRender?: (route: ItemType, params: T, routes: ItemType[], paths: string[]) => React.ReactNode;
route: ItemType,
params: any,
routes: ItemType[],
paths: string[],
) => React.ReactNode;
} }
const getPath = (params: any, path?: string) => { const getPath = <T extends Record<PropertyKey, any> = any>(params: T, path?: string) => {
if (path === undefined) { if (path === undefined) {
return path; return path;
} }
let mergedPath = (path || '').replace(/^\//, ''); let mergedPath = (path || '').replace(/^\//, '');
Object.keys(params).forEach((key) => { Object.keys(params).forEach((key) => {
mergedPath = mergedPath.replace(`:${key}`, params[key]!); mergedPath = mergedPath.replace(`:${key}`, params[key]!);
@ -80,7 +74,7 @@ const getPath = (params: any, path?: string) => {
return mergedPath; return mergedPath;
}; };
const Breadcrumb = (props: BreadcrumbProps) => { const Breadcrumb = <T extends Record<PropertyKey, any> = any>(props: BreadcrumbProps<T>) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
separator = '/', separator = '/',
@ -113,7 +107,7 @@ const Breadcrumb = (props: BreadcrumbProps) => {
// generated by route // generated by route
const paths: string[] = []; const paths: string[] = [];
const itemRenderRoutes: any = items || legacyRoutes; const itemRenderRoutes = items || legacyRoutes;
crumbs = mergedItems.map((item, index) => { crumbs = mergedItems.map((item, index) => {
const { const {
@ -168,7 +162,7 @@ const Breadcrumb = (props: BreadcrumbProps) => {
onClick={onClick} onClick={onClick}
prefixCls={prefixCls} prefixCls={prefixCls}
> >
{mergedItemRender(item as BreadcrumbItemType, params, itemRenderRoutes, paths, href)} {mergedItemRender(item, params, itemRenderRoutes!, paths, href)}
</InternalBreadcrumbItem> </InternalBreadcrumbItem>
); );
}); });

View File

@ -37,7 +37,7 @@ export interface BreadcrumbItemProps extends SeparatorType {
overlay?: DropdownProps['overlay']; overlay?: DropdownProps['overlay'];
} }
export const InternalBreadcrumbItem = (props: BreadcrumbItemProps) => { export const InternalBreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) => {
const { prefixCls, separator = '/', children, menu, overlay, dropdownProps, href } = props; const { prefixCls, separator = '/', children, menu, overlay, dropdownProps, href } = props;
// Warning for deprecated usage // Warning for deprecated usage
@ -103,11 +103,15 @@ export const InternalBreadcrumbItem = (props: BreadcrumbItemProps) => {
return null; return null;
}; };
const BreadcrumbItem = (props: BreadcrumbItemProps) => { type CompoundedComponent = React.FC<BreadcrumbItemProps> & {
/** @internal */
__ANT_BREADCRUMB_ITEM: boolean;
};
const BreadcrumbItem: CompoundedComponent = (props) => {
const { prefixCls: customizePrefixCls, children, href, ...restProps } = props; const { prefixCls: customizePrefixCls, children, href, ...restProps } = props;
const { getPrefixCls } = React.useContext(ConfigContext); const { getPrefixCls } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls); const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
return ( return (
<InternalBreadcrumbItem {...restProps} prefixCls={prefixCls}> <InternalBreadcrumbItem {...restProps} prefixCls={prefixCls}>
{renderItem(prefixCls, restProps as ItemType, children, href)} {renderItem(prefixCls, restProps as ItemType, children, href)}

View File

@ -384,4 +384,19 @@ describe('Breadcrumb', () => {
); );
expect(document.querySelector('.ant-dropdown')).toBeTruthy(); expect(document.querySelector('.ant-dropdown')).toBeTruthy();
}); });
it('Breadcrumb params type test', () => {
interface Params {
key1?: number;
key2?: string;
}
expect(
<Breadcrumb<Params>
params={{
key1: 1,
key2: 'test',
}}
/>,
).toBeTruthy();
});
}); });