Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Typescript, is there any way to typecheck passed-in JSX.Element's?

Consider this simple case:

Client of library:

class ClientComponent extends React.Component<any,any> {
    render() {
        const myNestedElement = (<LibNestedComponent/>)
        return <LibComponent nested={myNestedElement}/> 
    }
}

Library:

class LibNestedComponent extends React.Component<any,any> {
    render() { return <div>nested stuff</div> }
}

interface LibComponentProps { nested: JSX.Element }
class LibComponent  extends React.Component<LibComponentProps,any> {
    render() {
        return <div>{this.props.nested}</div>
    }
}

As the author of Lib, I'd like to be able to tell my LibComponent clients, via the LibComponentProps interface, that the passed-in nested prop must be an element of type LibNestedComponent - not just any old j.random element. But AFAICT, there's no way to do this; the Typescript doc even says:

The JSX result type.  By default the result of a JSX expression is typed as any. You can customize the type by specifying the JSX.Element interface. However, it is not possible to retrieve type information about the element, attributes or children of the JSX from this interface. It is a black box.

Does anyone have a workaround that achieves this kind of typechecking without too much pain?

(The example is deliberately trivial and is not meant to be a sensible use-case.)

like image 456
Ed Staub Avatar asked Dec 30 '25 13:12

Ed Staub


2 Answers

Apart from my comment, I don't know if there is a typescript way to restrict the type of component that client component can pass. But there is a way through which you can determine the type of component that was passed as a prop.

You can check the name of the component which was passed and see which type is it.

if (this.props.nested.type.name === 'LibNestedComponent') {
   console.log('A valid component is passed');
} else {
   console.log('Invalid component is passed');
}

where nested is the component you passed in the example you provided.

In the below picture you can see the name of the component.

enter image description here

But again, this would be a run-time detection.

like image 57
Hardik Modha Avatar answered Jan 01 '26 08:01

Hardik Modha


You can check the type of this.props.nested using the object

if (this.props.nested.type !== LibNestedComponent) {
   throw new Error('Invalid prop passed. Make sure that an instance of LibNestedComponent is passed through the nested prop')
}

The problem with Hardik's answer is that, in case your code gets minified, the value of type.name will change and your code will fail. So you should go for the type property directly instead.

like image 28
Nahush Farkande Avatar answered Jan 01 '26 09:01

Nahush Farkande



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!