From aad23fbf16c82f9f1b4474e3b3f6b49df02e9e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Tammerg=C3=A5rd?= Date: Fri, 19 May 2023 16:39:56 +0200 Subject: [PATCH 1/4] Add ComponentProps reference as first React Types example --- docs/react-types/ComponentProps.md | 57 ++++++++++++++++++++++++++++++ docs/react-types/index.md | 7 ++++ 2 files changed, 64 insertions(+) create mode 100644 docs/react-types/ComponentProps.md create mode 100644 docs/react-types/index.md diff --git a/docs/react-types/ComponentProps.md b/docs/react-types/ComponentProps.md new file mode 100644 index 00000000..a7595b63 --- /dev/null +++ b/docs/react-types/ComponentProps.md @@ -0,0 +1,57 @@ +--- +title: ComponentProps +--- + +`ComponentProps` is a utility type that lets you grab all valid props of an HTML or SVG element, or infer prop type for a component. + +## Parameters + +- `T extends keyof JSX.IntrinsicElements | JSXElementConstructor` + +`keyof JSX.IntrinsicElements` is a set of all HTML and SVG elements, such as `"div"`, `"h1"` and `"path"`. + +`JSXElementConstructor` is the type of a function or class component. + +## Usage + +### Getting all valid props of an HTML or SVG element + +`ComponentProps` can be used to create a type that includes all valid `div` props. + +```tsx +interface Props extends ComponentProps<"div"> { + text: string; +} + +function Component({ className, children, text }: Props) { + // ... +} +``` + +### Infer prop types from a component + +In some cases, you might want to infer the type of a component's props. + +```tsx +interface Props { + text: string; +} + +function Component(props: Props) { + // ... +} + +type MyType = ComponentProps; +// ^? type MyType = Props +``` + +The type of a specific prop can also be inferred this way. Let's say you are using an `` component from a component library. The component takes a `name` prop that determines what icon is shown. You need to use the type of `name` in your app, but it's not made available by the library. No problem! + +```tsx +import { Icon } from "component-library"; + +type IconName = ComponentProps["name"]; +// ^? type IconName = "warning" | "checkmark" | ... +``` + +Needless to say, `ComponentProps` can be very useful! diff --git a/docs/react-types/index.md b/docs/react-types/index.md new file mode 100644 index 00000000..599162bd --- /dev/null +++ b/docs/react-types/index.md @@ -0,0 +1,7 @@ +--- +title: React Types +--- + +`@types/react` makes some types available that can be very useful. Here's a list in alphabetical order with links to the detailed reference pages. + +- [`ComponentProps`](/docs/react-types/ComponentProps) From df158106a3a897664cf904bc9731f9aae9c3e4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Tammerg=C3=A5rd?= Date: Tue, 23 May 2023 09:14:05 +0200 Subject: [PATCH 2/4] Update based on feedback --- docs/react-types/ComponentProps.md | 32 ++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/docs/react-types/ComponentProps.md b/docs/react-types/ComponentProps.md index a7595b63..afa847cf 100644 --- a/docs/react-types/ComponentProps.md +++ b/docs/react-types/ComponentProps.md @@ -2,19 +2,23 @@ title: ComponentProps --- -`ComponentProps` is a utility type that lets you grab all valid props of an HTML or SVG element, or infer prop type for a component. +`ComponentProps` is a utility type that lets you grab all valid props of an element, or infer prop type of a component. -## Parameters +:::note + +Prefer `ComponentPropsWithRef` if ref is forwarded and `ComponentPropsWithoutRef` when ref is not forwarded. -- `T extends keyof JSX.IntrinsicElements | JSXElementConstructor` +::: -`keyof JSX.IntrinsicElements` is a set of all HTML and SVG elements, such as `"div"`, `"h1"` and `"path"`. +## Parameters -`JSXElementConstructor` is the type of a function or class component. +- `T`: An element type. Examples include: + - An HTML or SVG element such as `"div"`, `"h1"` or `"path"`. + - A component type, such as `typeof Component`. ## Usage -### Getting all valid props of an HTML or SVG element +### Getting all valid props of an element `ComponentProps` can be used to create a type that includes all valid `div` props. @@ -23,8 +27,8 @@ interface Props extends ComponentProps<"div"> { text: string; } -function Component({ className, children, text }: Props) { - // ... +function Component({ className, children, text, ...props }: Props) { + // `Props` includes `text` in addition to all valid `div` props } ``` @@ -45,7 +49,15 @@ type MyType = ComponentProps; // ^? type MyType = Props ``` -The type of a specific prop can also be inferred this way. Let's say you are using an `` component from a component library. The component takes a `name` prop that determines what icon is shown. You need to use the type of `name` in your app, but it's not made available by the library. No problem! +#### Inferring specific prop type + +The type of a specific prop can also be inferred this way. Let's say you are using an `` component from a component library. The component takes a `name` prop that determines what icon is shown. You need to use the type of `name` in your app, but it's not made available by the library. You could create a custom type: + +```tsx +type IconName = "warning" | "checkmark"; +``` + +However, this type if not really reflecting the actual set of icons made available by the library. A better solution is to infer the type: ```tsx import { Icon } from "component-library"; @@ -53,5 +65,3 @@ import { Icon } from "component-library"; type IconName = ComponentProps["name"]; // ^? type IconName = "warning" | "checkmark" | ... ``` - -Needless to say, `ComponentProps` can be very useful! From 23e0d89dee7cea905f7e0c71817dc1e408c2d2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Tammerg=C3=A5rd?= Date: Wed, 24 May 2023 12:49:29 +0200 Subject: [PATCH 3/4] Add example with Pick --- docs/react-types/ComponentProps.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/react-types/ComponentProps.md b/docs/react-types/ComponentProps.md index afa847cf..06da1f0c 100644 --- a/docs/react-types/ComponentProps.md +++ b/docs/react-types/ComponentProps.md @@ -1,12 +1,12 @@ --- -title: ComponentProps +title: ComponentProps --- -`ComponentProps` is a utility type that lets you grab all valid props of an element, or infer prop type of a component. +`ComponentProps` is a utility type that lets you grab all valid props of an element, or infer prop type of a component. :::note -Prefer `ComponentPropsWithRef` if ref is forwarded and `ComponentPropsWithoutRef` when ref is not forwarded. +Prefer `ComponentPropsWithRef` if ref is forwarded and `ComponentPropsWithoutRef` when ref is not forwarded. ::: @@ -20,7 +20,7 @@ Prefer `ComponentPropsWithRef` if ref is forwarded and `ComponentPropsWithout ### Getting all valid props of an element -`ComponentProps` can be used to create a type that includes all valid `div` props. +`ComponentProps` can be used to create a type that includes all valid `div` props. ```tsx interface Props extends ComponentProps<"div"> { @@ -63,5 +63,14 @@ However, this type if not really reflecting the actual set of icons made availab import { Icon } from "component-library"; type IconName = ComponentProps["name"]; -// ^? type IconName = "warning" | "checkmark" | ... +// ^? type IconName = "warning" | "checkmark" +``` + +You can also use the `Pick` utility type to accomplish the same thing: + +```tsx +import { Icon } from "component-library"; + +type IconName = Pick, "name">; +// ^? type IconName = "warning" | "checkmark" ``` From b41e6fbff22dd32f3fe90ee8531bf6c260b3a8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Tammerg=C3=A5rd?= Date: Mon, 29 May 2023 12:33:16 +0200 Subject: [PATCH 4/4] Change from Element to ElementType --- docs/react-types/ComponentProps.md | 20 ++++++++++---------- docs/react-types/index.md | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/react-types/ComponentProps.md b/docs/react-types/ComponentProps.md index 06da1f0c..50ed42a8 100644 --- a/docs/react-types/ComponentProps.md +++ b/docs/react-types/ComponentProps.md @@ -1,26 +1,26 @@ --- -title: ComponentProps +title: ComponentProps --- -`ComponentProps` is a utility type that lets you grab all valid props of an element, or infer prop type of a component. +`ComponentProps` constructs a type with all valid props of an element or inferred props of a component. :::note -Prefer `ComponentPropsWithRef` if ref is forwarded and `ComponentPropsWithoutRef` when ref is not forwarded. +Prefer `ComponentPropsWithRef` if ref is forwarded and `ComponentPropsWithoutRef` when ref is not forwarded. ::: ## Parameters -- `T`: An element type. Examples include: - - An HTML or SVG element such as `"div"`, `"h1"` or `"path"`. +- `ElementType`: An element type. Examples include: + - An HTML or SVG element string literal such as `"div"`, `"h1"` or `"path"`. - A component type, such as `typeof Component`. ## Usage -### Getting all valid props of an element +### Get all valid props of an element -`ComponentProps` can be used to create a type that includes all valid `div` props. +`ComponentProps` can be used to create a type that includes all valid `div` props. ```tsx interface Props extends ComponentProps<"div"> { @@ -28,11 +28,11 @@ interface Props extends ComponentProps<"div"> { } function Component({ className, children, text, ...props }: Props) { - // `Props` includes `text` in addition to all valid `div` props + // `props` includes `text` in addition to all valid `div` props } ``` -### Infer prop types from a component +### Infer component props type In some cases, you might want to infer the type of a component's props. @@ -49,7 +49,7 @@ type MyType = ComponentProps; // ^? type MyType = Props ``` -#### Inferring specific prop type +#### Infer specific prop type The type of a specific prop can also be inferred this way. Let's say you are using an `` component from a component library. The component takes a `name` prop that determines what icon is shown. You need to use the type of `name` in your app, but it's not made available by the library. You could create a custom type: diff --git a/docs/react-types/index.md b/docs/react-types/index.md index 599162bd..12171892 100644 --- a/docs/react-types/index.md +++ b/docs/react-types/index.md @@ -4,4 +4,4 @@ title: React Types `@types/react` makes some types available that can be very useful. Here's a list in alphabetical order with links to the detailed reference pages. -- [`ComponentProps`](/docs/react-types/ComponentProps) +- [`ComponentProps`](/docs/react-types/ComponentProps)