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

View File

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

View File

@ -384,4 +384,19 @@ describe('Breadcrumb', () => {
);
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();
});
});