React: typescript

Carlos Costa

Some tips to use typescript with react.

Typed props


Applying types to props is a good practice to avoid errors and to make the code more readable.

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  children: string
}

function Button({ children, ...props }: ButtonProps) {
  return <button {...props}> {children} </button>
}

In the previous example, we are extending the default props of a button element and adding a new prop called children that is required and must be a string.

  • React.ButtonHTMLAttributes<HTMLButtonElement>: This is a type that extends the default props of a button element.

Typed state


When we are using useState hook, we can define the type of the state.

interface User {
  name: string
  age: number
}

const [user, setUser] = useState<User>({ name: 'John Doe', age: 20 })

Usin literals is also possible.

type Status = 'Processing' | 'Accepted' | 'Denied'
const [status, setStatus] = useState<Status>('Processing')

here, the status state can only be one of the three values.

We can also use a object as state.

const [user, setUser] = useState<{ name: string; age: number }>({
  name: 'John Doe',
  age: 20,
})

And a function.

const [action, setAction] = useState<(arg: string) => string>(
  (arg: string) => {
    return 'hello world!'
  }
)

Using all examples:

useEffect(() => {
  setCount(10)
  setStatus('Finished')
  setPerson({ name: 'Maria', age: 22 })
  setAction(() => 'foo bar span')
}, [])

Typed refs


When we are using useRef hook, we can define the type of the ref.

const h1Ref = useRef<HTMLHeadingElement>(null)
const divRef = useRef<HTMLDivElement>(null)
const imageRef = useRef<HTMLImageElement>(null)
const inputRef = useRef<HTMLInputElement>(null)

return (
  <Fragment>
    <h1 ref={h1Ref} />
    <div ref={divRef} />
    <img ref={imageRef} />
    <input ref={inputRef} />
  </Fragment>
)

Typed events


function clickHandle(event: React.MouseEvent<HTMLButtonElement>) {
  console.log(event.clientX, event.clientY)
}

function changeHandle(event: React.ChangeEvent<HTMLInputElement>) {
  console.log(event.target.value)
}

function syntheticHandle(event: React.SyntheticEvent) {
  event.preventDefault()
}

return (
  <div>
    <button onClick={clickHandle}> Click me! </button>
    <input onChange={changeHandle} type="text" />
  </div>
)
  • React.MouseEvent<HTMLButtonElement>: This is a type that extends the default props of a button element.
  • React.ChangeEvent<HTMLInputElement>: This is a type that extends the default props of a input element.
  • React.SyntheticEvent: This is a type that extends the default props of a event element.

Typed children


interface Props {
  children: React.ReactElement
}

function Component({ children }: Props) {
  return <div> {children} </div>
}
  • React.ReactElement: This is a type that extends the default props of a element element.
  • React.ReactNode: This is a type that extends the default props of a node element.

References