Archives

Archives / 2016 / July
  • Consuming Javascript libraries from TypeScript without type definition files

    There are cases where you need to consume Javascript libraries or, for example, ReactJS components written in Javascript from your TypeScript code. Possible reasons:
    • You find a great library or component "out in the wild" written in Javascript
    • One of your team-members does not know/does not want to write TypeScript
    • You want to consume components from an existing library or component set writen in Javascript
    Assume the situation where a ReactJS component MyComponent.jsx written in Javascript must be consumed from a component Home.tsx:

    The file MyComponent.jsx:

    import * as React from 'react';

    export class MyComponent extends React.Component {
      constructor(props) { super(props); }
      render() { return (<h1>Hello from MyComponent</h1>); }
    }

    We could import this component in different ways:
    import {MyComponent} from './MyComponent'; // ERROR: Cannot find module './MyComponent'
    const MyComponent = require('./MyComponent'); // Warning if used as <MyComponent/>

    // see https://codereviewvideos.com/blog/warning-react-createelement/
    const X = require('./MyComponent'); // OK if used as <X.MyComponent/>
    const MyComponent = require('./MyComponent').MyComponent; // OK
    const MyComponent = require('./MyComponent').default;// OK if defined as export default class MyComponent
    const {MyComponent} = require('./MyComponent'); // OK, it's possible to destructure multiple components

    For details on how to specify types for desctructured object parameters see destructured object parameters in TypeScript.

    So if we want to consume the above JavaScript component from TypeScript in the component Home.tsx:
    import * as React from 'react';
    const MyComponent = require('./MyComponent').MyComponent;

    export class Home extends React.Component<any, any> {
    render() { return (<div><MyComponent /></div>); }
    }