Upgrading to using TypeScript with plugin-utils 2.0.0

To upgrade to version 2.0.0 and enable TypeScript support first update the package.json to include at least version 2.0.0 of @infomaker/writer-plugin-utils:

    "@infomaker/writer-plugin-utils": "^2.0.0"

Run npm install to install the version.

$ npm install

Manually Run the writer-plugin-utils upgrade command

$ npx writer-jumpstart-upgrade

This will update/copy some files and install new dependencies needed for TypeScript.

Rename .js files in src directory to .ts

This will also show a bunch of errors. Time to learn TypeScript and fix them all! Yes, your build will break until you fix them all.

TypeScript Resources

Update entrypoint in webpack configs

Change src/index.js to src/index.ts in these files:

    __tooling__/webpack/webpack.dev.js
    __tooling__/webpack/webpack.prod.js

Start Dev Build

$ npm start

This will continually scream at you until you fix all the TypeScript lint errors.

Note on building

We are using webpack and babel-loader only to transpile TypeScript into javascript, this means that the typescript compiler is not running when any build scripts are used. The result of this might be a successful build with no errors, but your editor will still report errors, because it is running the typecript compiler internally.

You should still take the errors in the editor seriously even if the build scripts are working fine.

Testing Your Build

When your local dev build works, and the local plugin has been tested to run in a Writer, run the following to ensure that the plugin can build when it's pushed to bitbucket:

$ npm run build && npm run build-dev && npm start

If there are no errors when running this, then the plugin should build correctly in bitbucket-pipelines.

Writer Typings

When moving to TypeScript you might discover a bug in the 'writer' modules type definitions, maybe a function's JSDoc isn't properly set up so the optional parameter does not show up as optional in the type definition.

When this happens, correct the JSDoc comment in the writer-client-project and commit to feature/client-build-branch.

Then go to the infomaker/writer-typings-project, and create a pull request with a description of what will be fixed and an updated version number on the 'writer'-module.

Workarounds and Gotchas

...args in my constructor won't play nice

This will no longer work since it makes TypeScript angry:

class MyComponent extends Component {
    constructor(...args) {
        super(...args)
    }
}

Instead we need to be more explicit and add the correct parameters to constructor:

class MyComponent extends Component {
    constructor(parent: Component, ...args: unknown[]) {
        super(parent, ...args)
    }
}

I can't make this one line work and I'm tired of trying to fix it!

In special cases you can add the following comment above a line that you just can't get to work using TypeScript, but you know is fine when it actually compiles.

// @ts-ignore: Ignore please
this line is ignored

It is important to add a reason after @ts-ignore, or the linter will still complain.

This will make the compiler ignore the line below it and it should build correctly.

Only when absolutely necessary should this be used:

class MyComponent extends Component {
    constructor(parent: Component, ...args: unknown[]) {
        
        // @ts-ignore: Ignore please
        const foo = 'Something impossible to get to work in TypeScript for some reason'

    }
}

One example of this is when creating a Validator class where we for some reason add a static property called name on the class. We have our reasons and can't easily change this, but TypeScript will be mad unless we add the @ts-ignore comment to it.

class DraftValidator extends Validator {
    // @ts-ignore: Override readonly native name property is not a good idea, but it is necessary in this case
    static get name() {
        return 'DraftValidator'
    }
}