2022-07-19 10:12:15 +01:00
|
|
|
---
|
|
|
|
tags:
|
|
|
|
- typescript
|
|
|
|
- react
|
|
|
|
---
|
|
|
|
|
|
|
|
# Props
|
|
|
|
|
2022-08-04 12:11:33 +01:00
|
|
|
## Types or interfaces?
|
|
|
|
|
|
|
|
They are mostly interchangeable but there are some specific differences
|
|
|
|
|
|
|
|
### Interfaces
|
|
|
|
|
|
|
|
- Classes and other interfaces can extend an interface but not a type
|
|
|
|
|
|
|
|
```ts
|
|
|
|
interface Animal {
|
|
|
|
name: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Bear extends Animal {
|
|
|
|
honey: boolean;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-02-02 15:58:13 +00:00
|
|
|
- You can add properties to an interface without generating a double declaration
|
|
|
|
error:
|
2022-08-04 12:11:33 +01:00
|
|
|
|
|
|
|
```ts
|
|
|
|
interface Window {
|
2024-02-17 13:27:49 +00:00
|
|
|
}
|
2022-08-04 12:11:33 +01:00
|
|
|
|
|
|
|
interface Window {
|
|
|
|
ts: TypeScriptAPI;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Types
|
|
|
|
|
|
|
|
You can create unions with types but not interfaces.
|
|
|
|
|
2024-02-02 15:58:13 +00:00
|
|
|
> The consensus seems to be that interfaces should be used over types unless
|
|
|
|
> there are ocassions when you do not want a type to be extendable /
|
|
|
|
> redeclarable. Or when you want to use unions.
|
2022-08-04 12:11:33 +01:00
|
|
|
|
|
|
|
## How we type props
|
|
|
|
|
2024-02-02 15:58:13 +00:00
|
|
|
The custom is to type props as an interface. This way we can easily type
|
|
|
|
function prop types.
|
2022-08-04 12:11:33 +01:00
|
|
|
|
2022-07-19 10:12:15 +01:00
|
|
|
```tsx
|
|
|
|
interface IProps {
|
|
|
|
people: {
|
|
|
|
name: string;
|
|
|
|
age: number;
|
|
|
|
note?: string;
|
|
|
|
}[];
|
|
|
|
}
|
|
|
|
|
|
|
|
const List: React.FC<IProps> = ({people}: IProps) => {
|
|
|
|
return()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Note we say that the props into the func component are of type IProps
|
|
|
|
// And we destructure the people key
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
Then in the parent:
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
|
|
|
const [people, setPeople] = useState<IState['people']>({});
|
|
|
|
|
|
|
|
<List props={people}>
|
|
|
|
|
|
|
|
```
|
|
|
|
|
2022-08-04 12:11:33 +01:00
|
|
|
## Common types for props
|
|
|
|
|
|
|
|
### Object with any number of properties
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
interface IProps {
|
|
|
|
obj: {};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Array of objects
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
interface IProps {
|
|
|
|
val1: string;
|
|
|
|
val2: boolean;
|
|
|
|
}
|
|
|
|
[];
|
|
|
|
```
|
|
|
|
|
|
|
|
### Functions
|
|
|
|
|
|
|
|
```tsx
|
|
|
|
|
|
|
|
// Function that doesn't receive or return anything
|
|
|
|
interface IProps {
|
|
|
|
onClick: () => void;
|
|
|
|
}[]
|
|
|
|
|
|
|
|
// Function with named parameter
|
|
|
|
interface IProps {
|
|
|
|
onClick: (id: number) => void;
|
|
|
|
}[]
|
|
|
|
|
|
|
|
// Function that takes an event
|
|
|
|
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
|
|
```
|
|
|
|
|
|
|
|
### Other React components
|
|
|
|
|
|
|
|
```js
|
|
|
|
interface IProps {
|
|
|
|
children: React.ReactNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface IProps {
|
|
|
|
children: JSX.Element;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-02-02 15:58:13 +00:00
|
|
|
`React.ReactNode` covers everything that React can render. This should be
|
|
|
|
definitely used when the prop is a child component, otherwise `JSX.element` is
|
|
|
|
ok.
|
2022-08-04 12:11:33 +01:00
|
|
|
|
2022-07-19 10:12:15 +01:00
|
|
|
<p style="color: red;">Should I use type or interface? What is consensus?</p>
|