zefciu
zefciu

Reputation: 2047

How to specify type parameters in typescript declaration?

I have created a React component that takes a class of its child component. This component is responsible for providing the user ability to login via the OIDC protocol and if the user is logged in – rendering the child passing the user object as a prop (the child would use it in API calls).

This is how my component is declared:

type AuthProps = {
  childClass: typeof React.Component;
}

type AuthState = {
  user: Maybe<User>
}

class Auth extends React.Component<AuthProps, AuthState> {
}

Then I render my child element like:

<this.props.childClass user={this.state.user} />

This configuration works just fine. But what if I wanted more type safety? Namely if I want to ensure that childClass supports the user prop? I tried to type it like:

  childClass: typeof ReactComponent<{user: Maybe<User>}>,

this, however is not even a proper syntax. Is it possible to narrow the type of childClass somehow?

Upvotes: 0

Views: 53

Answers (1)

ford04
ford04

Reputation: 74770

Alternative 1: React.ComponentType

type AuthProps = {
  childClass: React.ComponentType<{ user: Maybe<User> }>;
};

class Auth extends React.Component<AuthProps, AuthState> {
  render() {
    return <this.props.childClass user={this.state.user} />;
  }
}

React.ComponentType is a built-in type (replaces your typeof React.Component) and allows both class or function components to be used.

Alernative 2: Render Props

type AuthProps2 = {
  childClass: (user: Maybe<User>) => JSX.Element;
};

class Auth2 extends React.Component<AuthProps2, AuthState> {
  render() {
    return this.props.childClass(this.state.user);
  }
}

This is the preferred and safer alternative. Given the client passed an inline component like

const App = () => <Auth childClass={props => <div>{props.user}</div>} />;

, it prevents performance penalties of the first solution. Alternative 1 would remount the component in every render cycle, as the component instance changes each time (look here for a related article).

Upvotes: 1

Related Questions