Skip to content

Commit fa741bd

Browse files
committed
Tweak explanations of object types in Basic Prop Types Examples (#582)
* Reorder and reword some of the basic prop type examples Put the recommended approaches before the non-recommended approaches, and reword some of the decriptions of object types * Add details section with more description of object types * Add note about Map * Update README.md
1 parent 831a3e4 commit fa741bd

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

README.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,11 +1096,8 @@ type AppProps = {
10961096
names: string[];
10971097
/** string literals to specify exact string values, with a union type to join them together */
10981098
status: "waiting" | "success";
1099-
/** any object as long as you dont use its properties (NOT COMMON but useful as placeholder) */
1100-
obj: object;
1101-
obj2: {}; // almost the same as `object`, exactly the same as `Object`
1102-
/** an object with any number of properties (PREFERRED) */
1103-
obj3: {
1099+
/** an object with known properties (but could have more at runtime) */
1100+
obj: {
11041101
id: string;
11051102
title: string;
11061103
};
@@ -1109,13 +1106,15 @@ type AppProps = {
11091106
id: string;
11101107
title: string;
11111108
}[];
1109+
/** any non-primitive value - can't access any properties (NOT COMMON but useful as placeholder) */
1110+
obj2: object;
1111+
/** an interface with no required properties - (NOT COMMON, except for things like `React.Component<{}, State>`) */
1112+
obj3: {};
11121113
/** a dict object with any number of properties of the same type */
11131114
dict1: {
11141115
[key: string]: MyTypeHere;
11151116
};
11161117
dict2: Record<string, MyTypeHere>; // equivalent to dict1
1117-
/** any function as long as you don't invoke it (not recommended) */
1118-
onSomething: Function;
11191118
/** function that doesn't take or return anything (VERY COMMON) */
11201119
onClick: () => void;
11211120
/** function with named prop (VERY COMMON) */
@@ -1124,6 +1123,8 @@ type AppProps = {
11241123
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
11251124
/** alternative function type syntax that takes an event (VERY COMMON) */
11261125
onClick(event: React.MouseEvent<HTMLButtonElement>): void;
1126+
/** any function as long as you don't invoke it (not recommended) */
1127+
onSomething: Function;
11271128
/** an optional prop (VERY COMMON!) */
11281129
optional?: OptionalType;
11291130
/** when passing down the state setter function returned by `useState` to a child component. `number` is an example, swap out with whatever the type of your state */
@@ -1133,6 +1134,17 @@ type AppProps = {
11331134

11341135
Notice we have used the TSDoc `/** comment */` style here on each prop. You can and are encouraged to leave descriptive comments on reusable components. For a fuller example and discussion, see our [Commenting Components](https://react-typescript-cheatsheet.netlify.app/docs/advanced/misc_concerns/#commenting-components) section in the Advanced Cheatsheet.
11351136

1137+
<details>
1138+
<summary>More on object types: <code>object</code>, <code>{"{}"}</code>, etc</summary>
1139+
1140+
In Typescript, it's generally best to use specific types for objects. In most cases, this means a literal type like <code>{ id: string; name: string }</code>. In cases where there isn't a fixed structure for an object, you likely either want an index signature (possibly with the <code>Record</code> shorthand) - if there are values of a certain type, but the keys can change - or else <a href="https://www.typescriptlang.org/docs/handbook/2/generics.html">generics</a> - if the object structure is more-or-less an arbitrary black-box.
1141+
1142+
Another approach to objects is the <code>Map</code> data structure, but this is somewhat uncommon to use in React, because React prefers data to be changed immutably (e.g. <code>setUser({...user, name: newName})</code>), while Maps are mutable data structures.
1143+
1144+
"Vague" object types like <code>object</code>, <code>{}</code> are fairly niche and should be rarely used, and may function differently than you expect. <code>object</code> is any non-primitive value: this includes things like functions and arrays and constructors, not just "simple" objects. And <code>{}</code> is perhaps better thought of as "an interface with no required properties", not "an empty object" - in practice this type allows anything except <code>null</code> or <code>undefined</code>. <code>Object</code> behaves the same as <code>{}</code> and is basically never used.
1145+
1146+
</details>
1147+
11361148
#### Useful React Prop Type Examples
11371149

11381150
Relevant for components that accept other React components as props.

docs/basic/getting-started/basic-type-examples.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,8 @@ type AppProps = {
1818
names: string[];
1919
/** string literals to specify exact string values, with a union type to join them together */
2020
status: "waiting" | "success";
21-
/** any object as long as you dont use its properties (NOT COMMON but useful as placeholder) */
22-
obj: object;
23-
obj2: {}; // almost the same as `object`, exactly the same as `Object`
24-
/** an object with any number of properties (PREFERRED) */
25-
obj3: {
21+
/** an object with known properties (but could have more at runtime) */
22+
obj: {
2623
id: string;
2724
title: string;
2825
};
@@ -31,13 +28,15 @@ type AppProps = {
3128
id: string;
3229
title: string;
3330
}[];
31+
/** any non-primitive value - can't access any properties (NOT COMMON but useful as placeholder) */
32+
obj2: object;
33+
/** an interface with no required properties - (NOT COMMON, except for things like `React.Component<{}, State>`) */
34+
obj3: {};
3435
/** a dict object with any number of properties of the same type */
3536
dict1: {
3637
[key: string]: MyTypeHere;
3738
};
3839
dict2: Record<string, MyTypeHere>; // equivalent to dict1
39-
/** any function as long as you don't invoke it (not recommended) */
40-
onSomething: Function;
4140
/** function that doesn't take or return anything (VERY COMMON) */
4241
onClick: () => void;
4342
/** function with named prop (VERY COMMON) */
@@ -46,6 +45,8 @@ type AppProps = {
4645
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
4746
/** alternative function type syntax that takes an event (VERY COMMON) */
4847
onClick(event: React.MouseEvent<HTMLButtonElement>): void;
48+
/** any function as long as you don't invoke it (not recommended) */
49+
onSomething: Function;
4950
/** an optional prop (VERY COMMON!) */
5051
optional?: OptionalType;
5152
/** when passing down the state setter function returned by `useState` to a child component. `number` is an example, swap out with whatever the type of your state */
@@ -55,6 +56,17 @@ type AppProps = {
5556

5657
Notice we have used the TSDoc `/** comment */` style here on each prop. You can and are encouraged to leave descriptive comments on reusable components. For a fuller example and discussion, see our [Commenting Components](https://react-typescript-cheatsheet.netlify.app/docs/advanced/misc_concerns/#commenting-components) section in the Advanced Cheatsheet.
5758

59+
<details>
60+
<summary>More on object types: <code>object</code>, <code>{"{}"}</code>, etc</summary>
61+
62+
In Typescript, it's generally best to use specific types for objects. In most cases, this means a literal type like <code>{ id: string; name: string }</code>. In cases where there isn't a fixed structure for an object, you likely either want an index signature (possibly with the <code>Record</code> shorthand) - if there are values of a certain type, but the keys can change - or else <a href="https://www.typescriptlang.org/docs/handbook/2/generics.html">generics</a> - if the object structure is more-or-less an arbitrary black-box.
63+
64+
Another approach to objects is the <code>Map</code> data structure, but this is somewhat uncommon to use in React, because React prefers data to be changed immutably (e.g. <code>setUser({...user, name: newName})</code>), while Maps are mutable data structures.
65+
66+
"Vague" object types like <code>object</code>, <code>{}</code> are fairly niche and should be rarely used, and may function differently than you expect. <code>object</code> is any non-primitive value: this includes things like functions and arrays and constructors, not just "simple" objects. And <code>{}</code> is perhaps better thought of as "an interface with no required properties", not "an empty object" - in practice this type allows anything except <code>null</code> or <code>undefined</code>. <code>Object</code> behaves the same as <code>{}</code> and is basically never used.
67+
68+
</details>
69+
5870
## Useful React Prop Type Examples
5971

6072
Relevant for components that accept other React components as props.

0 commit comments

Comments
 (0)