From e5e8c73b912971d14fb49b9f0b465cb76718ddf5 Mon Sep 17 00:00:00 2001 From: petardev101 Date: Wed, 13 Feb 2019 02:51:55 -1000 Subject: [PATCH] add utility types section --- ADVANCED.md | 112 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 29 deletions(-) diff --git a/ADVANCED.md b/ADVANCED.md index 0630a9f..f1b662a 100644 --- a/ADVANCED.md +++ b/ADVANCED.md @@ -13,6 +13,7 @@ Expand Table of Contents +- [Section 0: Utility Types](#section-0-utility-types) - [Section 1: Reusable Components/Type Utilities](#section-1-reusable-componentstype-utilities) * [Higher Order Components](#higher-order-components-hocs) * [Render Props](#render-props) @@ -40,6 +41,88 @@ - [Section 4: @types/react and @types/react-dom APIs](#section-4-typesreact-and-typesreact-dom-apis) +# Section 0: Utility Types + +Handy Utility Types used in the rest of this cheatsheet, or commonly used with React+TS apps, with explanation on what they do and how they can help. We will assume knowledge of [mapped types and conditional types](https://mariusschulz.com/blog/series/typescript-evolution) like `Exclude` and `ReturnType` but try to build progressively upon them. + +
+ + Omit<T, K extends keyof T>: Subtract keys from one interface from the other. + + +```ts +/** + * Subtract keys from one interface from the other. + * + * @example + * interface One { one: string } + * interface Three { one: string, two: string } + * + * type Two = Omit; + * + * // The type of Two will be + * interface Two { two: string } + */ +type Omit = Pick>; +``` + +You can also supply string literals to omit: + +```ts +type SettingsPageProps = Omit +``` + +
+ +
+ + Optionalize<T extends K, K>: Remove from T the keys that are in common with K + + +```ts +/** + * Remove from T the keys that are in common with K + */ +type Optionalize = Omit; +``` + + An example usage is in our HOC section below. + +
+
+ + Nullable<T> or Maybe<T>: Make a Type into a Maybe Type + + +```ts +/** + * Make a Type into a Maybe Type + */ +type Nullable = T | null +type Maybe = T | undefined +``` + + Your choice of `null` or `undefined` depends on your approach toward missing values. Some folks feel strongly one way or the other. + +
+
+ + Dictionary<T>: Dictionary of string, value pairs + + +```ts +/** + * Dictionary of string, value pairs + */ +type Dictionary = { [key: string]: T } +``` + + `[key: string]` is a very handy trick in general. You can also modify dictionary fields with [Readonly](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html) or make them optional or Omit them, etc. + +
+ +[Something to add? File an issue](https://github.com/sw-yx/react-typescript-cheatsheet/issues/new). We respect the fact that naming and selection of examples here is arbitrary as the possible space is infinite. + # Section 1: Advanced Guides ## Higher Order Components (HoCs) @@ -88,29 +171,6 @@ Now when consuming the component you can omit the `primaryColor` prop or overrid **Declaring the HoC** -The following utilities will be needed. - -```ts -/** - * Generic type utility to subtract keys from one interface from the other. - * - * @example - * interface One { one: string } - * interface Three { one: string, two: string } - * - * type Two = Omit; - * - * // The type of Two will be - * interface Two { two: string } - */ -type Omit = Pick>; - -/** - * Remove from T the keys that are in common with K - */ -type Optionalize = Omit; -``` - The actual HoC. ```ts @@ -222,7 +282,6 @@ function Clickable(props: ButtonProps | AnchorProps) { They don't even need to be completely different props, as long as they have at least one difference in properties: ```tsx -type Omit = Pick> type LinkProps = Omit & { to?: string } function RouterLink(props: LinkProps): JSX.Element @@ -242,10 +301,7 @@ function RouterLink(props: LinkProps | AnchorProps) { Here is an example solution, see the further discussion for other solutions. *thanks to [@jpavon](https://github.com/sw-yx/react-typescript-cheatsheet/issues/12#issuecomment-394440577)* ```tsx -type Omit = Pick> - interface LinkProps {} - type AnchorProps = React.AnchorHTMLAttributes type RouterLinkProps = Omit @@ -274,8 +330,6 @@ const Link = ( If you want to conditionally render a component, sometimes is better to use [React's composition model](https://reactjs.org/docs/composition-vs-inheritance.html) to have simpler components and better to understand typings: ```tsx -type Omit = Pick> - type AnchorProps = React.AnchorHTMLAttributes type RouterLinkProps = Omit