For older applications, it's likely that you have some Class components. TypeScript works a little differently with these. The React.Component class is a generic class and it takes the props type as its first type argument. We will write out an alias for our props that I'll pass in the type argument space for the class. Child classes can also implement their own varIoUs methods for overriding parent methods, we'll also want to explicitly type the props in our constructor.
import * as React from "react"; interface CounterProps { initialCount?: number; className?: string; } interface CounterState { count: number; } class Counter extends React.Component<CounterProps, CounterState> { state: CounterState = { count: this.props.initialCount ?? 0, }; constructor(props: CounterProps) { super(props); this.increment = this.increment.bind(this); this.decrement = this.decrement.bind(this); } shouldComponentUpdate(nextProps: CounterProps, nextState: CounterState) { return shallowCompare(this, nextProps, nextState); } increment() { this.setState(({ count: prevCount }) => ({ count: prevCount + 1, })); } decrement() { this.setState(({ count: prevCount }) => ({ count: prevCount - 1, })); } render() { return ( <div className={this.props.className}> <button type="button" onClick={this.decrement} aria-label="Decrement"> - </button> <span>{this.state.count}</span> <button type="button" onClick={this.increment} aria-label="Increment"> + </button> </div> ); } } export { Counter };