diff --git a/docs/advanced/patterns_by_usecase.md b/docs/advanced/patterns_by_usecase.md index 6355f9ef..f6fc881b 100644 --- a/docs/advanced/patterns_by_usecase.md +++ b/docs/advanced/patterns_by_usecase.md @@ -10,34 +10,99 @@ sidebar_label: Useful Patterns by Use Case Usecase: you want to make a ` + + // no error + return ; +} + +// implementation +export interface ButtonProps extends React.ComponentProps<"button"> { + specialProp?: string; +} +export function Button(props: ButtonProps) { + const { specialProp, ...rest } = props; + // do something with specialProp + return ; +} +``` + + + +### Wrapping/Mirroring a Component Usecase: same as above, but for a React Component you don't have access to ```tsx const Box = (props: React.CSSProperties) =>
; -const Card = ({ - title, - children, - ...props -}: { title: string } & $ElementProps) => ( +const Card = ( + { title, children, ...props }: { title: string } & $ElementProps // new utility, see below +) => ( {title}: {children} @@ -57,7 +122,7 @@ declare type $ElementProps = T extends React.ComponentType : never; ``` -Advanced Example: +Usage: ```tsx import * as Recompose from "recompose"; @@ -73,7 +138,7 @@ export const defaultProps = < _thanks [dmisdm](https://github.com/typescript-cheatsheets/react/issues/23)_ -\*TODO: check how this conflicts/merges/duplicates with the Troubleshooting Handbook "Types I need weren't Exported" advice +_TODO: check how this conflicts/merges/duplicates with the Troubleshooting Handbook "Types I need weren't Exported" advice_ ## Polymorphic Components diff --git a/docs/advanced/types-react-ap.md b/docs/advanced/types-react-ap.md index 1bd8e231..baa19e88 100644 --- a/docs/advanced/types-react-ap.md +++ b/docs/advanced/types-react-ap.md @@ -28,15 +28,79 @@ Most Commonly Used Interfaces and Types Not Commonly Used but Good to know - `Ref` - used to type `innerRef` -- `ElementType` - used for higher order components or operations on components +- `ElementType` - used for higher order components or operations on components, e.g. [Polymorphic Components](https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase#polymorphic-components) - `ReactElement` - [can be used if you want to pass it to `cloneElement`](https://www.reddit.com/r/reactjs/comments/ia8sdi/any_other_typescript_users_constantly_confused/g1npahe/) aka it's pretty rarely used - `ComponentType` - used for higher order components where you don't specifically deal with the intrinsic components - `ReactPortal` - used if you specifically need to type a prop as a portal, otherwise it is part of `ReactNode` - `ComponentClass` - a complete interface for the produced constructor function of a class declaration that extends `Component`, often used to type external components instead of typing your own - `JSXElementConstructor` - anything that TypeScript considers to be a valid thing that can go into the opening tag of a JSX expression -- `ComponentProps` - props of a component +- `ComponentProps` - props of a component - most useful for [Wrapping/Mirroring a HTML Element](https://react-typescript-cheatsheet.netlify.app/docs/advanced/patterns_by_usecase#wrappingmirroring-a-html-element) - `ComponentPropsWithRef` - props of a component where if it is a class-based component it will replace the `ref` prop with its own instance type - `ComponentPropsWithoutRef` - props of a component without its `ref` prop +- `HTMLProps` and `HTMLAttributes` - these are the most generic versions, for global attributes (see a list of [attributes marked as "global attribute" on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes)). In general, prefer `React.ComponentProps`, `JSX.IntrinsicElements`, or [specialized HTMLAttributes interfaces](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a2aa0406e7bf269eef01292fcb2b24dee89a7d2b/types/react/index.d.ts#L1914-L2625): + +
+ + + List of specialized HTMLAttributes + + + Note that there are about 50 of these, which means there are some HTML elements which are not covered. + + - `AnchorHTMLAttributes` + - `AudioHTMLAttributes` + - `AreaHTMLAttributes` + - `BaseHTMLAttributes` + - `BlockquoteHTMLAttributes` + - `ButtonHTMLAttributes` + - `CanvasHTMLAttributes` + - `ColHTMLAttributes` + - `ColgroupHTMLAttributes` + - `DataHTMLAttributes` + - `DetailsHTMLAttributes` + - `DelHTMLAttributes` + - `DialogHTMLAttributes` + - `EmbedHTMLAttributes` + - `FieldsetHTMLAttributes` + - `FormHTMLAttributes` + - `HtmlHTMLAttributes` + - `IframeHTMLAttributes` + - `ImgHTMLAttributes` + - `InsHTMLAttributes` + - `InputHTMLAttributes` + - `KeygenHTMLAttributes` + - `LabelHTMLAttributes` + - `LiHTMLAttributes` + - `LinkHTMLAttributes` + - `MapHTMLAttributes` + - `MenuHTMLAttributes` + - `MediaHTMLAttributes` + - `MetaHTMLAttributes` + - `MeterHTMLAttributes` + - `QuoteHTMLAttributes` + - `ObjectHTMLAttributes` + - `OlHTMLAttributes` + - `OptgroupHTMLAttributes` + - `OptionHTMLAttributes` + - `OutputHTMLAttributes` + - `ParamHTMLAttributes` + - `ProgressHTMLAttributes` + - `SlotHTMLAttributes` + - `ScriptHTMLAttributes` + - `SelectHTMLAttributes` + - `SourceHTMLAttributes` + - `StyleHTMLAttributes` + - `TableHTMLAttributes` + - `TextareaHTMLAttributes` + - `TdHTMLAttributes` + - `ThHTMLAttributes` + - `TimeHTMLAttributes` + - `TrackHTMLAttributes` + - `VideoHTMLAttributes` + - `WebViewHTMLAttributes` + +
+ - all methods: `createElement`, `cloneElement`, ... are all public and reflect the React runtime API [@Ferdaber's note](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/pull/69): I discourage the use of most `...Element` types because of how black-boxy `JSX.Element` is. You should almost always assume that anything produced by `React.createElement` is the base type `React.ReactElement`. @@ -45,7 +109,7 @@ Not Commonly Used but Good to know - `Element` - the type of any JSX expression. You should ideally never need to see or use this, but you do because of [a limitation of TypeScript](https://github.com/microsoft/TypeScript/issues/21699). - `LibraryManagedAttributes` - It specifies other places where JSX elements can declare and initialize property types. Used to resolve static `defaultProps` and `propTypes` with the internal props type of a component. -- `IntrinsicElements` - every possible built-in component that can be typed in as a lowercase tag name in JSX +- `IntrinsicElements` - every possible built-in component that can be typed in as a lowercase tag name in JSX. If you're using this to get the attributes for a HTML element, `React.ComponentProps` may be more readable as it doesn't require knowing what "Intrinsic" means. Not commonly used but good to know