diff --git a/components/_util/__tests__/type.test.tsx b/components/_util/__tests__/type.test.tsx index 2f12cf7231..4b99b9c255 100644 --- a/components/_util/__tests__/type.test.tsx +++ b/components/_util/__tests__/type.test.tsx @@ -65,6 +65,22 @@ describe('type', () => { expect().toBeTruthy(); }); + + it('Support ForwardRefExoticComponent type', () => { + interface InnerProps { + test: number; + } + interface InnerRef { + bamboo: number; + } + type TestComponent = React.ForwardRefExoticComponent< + InnerProps & React.RefAttributes + >; + type ExtractedTestRef = GetRef; + + const a: ExtractedTestRef = { bamboo: 123 }; + expect(a).toBeTruthy(); + }); }); describe('GetProp', () => { diff --git a/components/_util/index.en-US.md b/components/_util/index.en-US.md new file mode 100644 index 0000000000..fbe300982d --- /dev/null +++ b/components/_util/index.en-US.md @@ -0,0 +1,45 @@ +--- +category: Components +title: Util +cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*rRDlT7ST8DUAAAAAAAAAAAAADrJ8AQ/original +coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*rRDlT7ST8DUAAAAAAAAAAAAADrJ8AQ/original +demo: + cols: 2 +group: + title: Other + order: 99 +--- + +Utilities are used to assist development and provide some common utility methods. + +## GetRef + +Get the `ref` property definition of the component, which is very useful for components that are not directly exposed or child components. + +```tsx +import type { GetRef, Select } from 'antd'; + +type SelectRefType = GetRef; // BaseSelectRef +``` + +## GetProps + +Get the `props` property definition of the component: + +```tsx +import type { Checkbox, GetProps } from 'antd'; + +type CheckboxGroupType = GetProps; +``` + +## GetProp + +Get the single `props` property definition of the component. It has encapsulated `NonNullable`, so you don't have to worry about being empty: + +```tsx +import type { GetProp, Select, SelectProps } from 'antd'; + +// Both of this can work +type SelectOptionType1 = GetProp[number]; +type SelectOptionType2 = GetProp[number]; +``` diff --git a/components/_util/index.zh-CN.md b/components/_util/index.zh-CN.md new file mode 100644 index 0000000000..c760623551 --- /dev/null +++ b/components/_util/index.zh-CN.md @@ -0,0 +1,46 @@ +--- +category: Components +title: Util +subtitle: 工具类 +cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*rRDlT7ST8DUAAAAAAAAAAAAADrJ8AQ/original +coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*rRDlT7ST8DUAAAAAAAAAAAAADrJ8AQ/original +demo: + cols: 2 +group: + title: 其他 + order: 99 +--- + +工具类用于辅助开发,提供一些常用的工具方法。 + +## GetRef + +获取组件的 `ref` 属性定义,这对于未直接暴露或者子组件的 `ref` 属性定义非常有用。 + +```tsx +import type { GetRef, Select } from 'antd'; + +type SelectRefType = GetRef; // BaseSelectRef +``` + +## GetProps + +获取组件的 `props` 属性定义: + +```tsx +import type { Checkbox, GetProps } from 'antd'; + +type CheckboxGroupType = GetProps; +``` + +## GetProp + +获取组件的单个 `props` 属性定义。它已经将 `NonNullable` 进行了封装,所以不用在考虑为空的情况: + +```tsx +import type { GetProp, Select, SelectProps } from 'antd'; + +// 以下两种都可以生效 +type SelectOptionType1 = GetProp[number]; +type SelectOptionType2 = GetProp[number]; +``` diff --git a/components/_util/type.ts b/components/_util/type.ts index b7a6e0411c..074ebdc7a4 100644 --- a/components/_util/type.ts +++ b/components/_util/type.ts @@ -24,9 +24,11 @@ type ReactRefComponent | string }> = ( props: Props, ) => React.ReactNode; +type ExtractRefAttributesRef = T extends React.RefAttributes ? P : never; + export type GetRef | React.Component> = T extends React.Component ? T - : T extends ReactRefComponent> - ? RefType + : T extends React.ComponentType + ? ExtractRefAttributesRef

: never; diff --git a/scripts/check-site.ts b/scripts/check-site.ts index 43196c0f79..35472502f2 100755 --- a/scripts/check-site.ts +++ b/scripts/check-site.ts @@ -13,7 +13,7 @@ const components = uniq( globSync('components/!(overview)/*.md', { cwd: join(process.cwd()), dot: false }).map((path) => path.replace(/(\/index)?((\.zh-cn)|(\.en-us))?\.md$/i, ''), ), -); +).filter((component) => !component.includes('_util')); describe('site test', () => { let server: http.Server | https.Server;