Linting TypeScript files in Ember.js
Tags: ember, typescript, eslint, javascript
Published: 2021-08-16 19:34:21

Do you have an Ember.js app that's written in TypeScript, but aren't sure how to get `eslint` to play well with TypeScript files? Read this tutorial to learn how.

First, let's make a new Ember app and immediately install TypeScript.

```
ember new my-app
cd my-app
ember install ember-cli-typescript
```

Now we have a brand new Ember app that is ready for TypeScript code. But you'll soon realize after generating some TypeScript files that writing obviously erroneous TypeScript code in these files doesn't yield any of the normal eslint messaging we get from `.js` files.

To fix this, we need to install a TypeScript parser and plugin, and let `eslint` know that we want to use this custom configuration. Here's how we do that:

```
npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin
```

This command will install two TypeScript `eslint` packages to your app. Now the only thing left to do is update your `eslint` configuration file so it can make use of these packages. In a standard Ember app, this file is located at `/.eslintrc.js`. 

We're only changing three lines here--we just need to tell `eslint` that we have a custom parser and an additional plugin we want to utilize:

```diff
// .eslintrc.js

module.exports = {
  root: true,
- parser: 'babel-eslint',
+ parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    requireConfigFile: false,
    babelOptions: {
      plugins: [
        ['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }],
      ],
    },
  },
  plugins: ['ember'],
  extends: [
    'eslint:recommended',
    'plugin:ember/recommended',
    'plugin:prettier/recommended',
  ],
  env: {
    browser: true,
  },
  rules: {},
  overrides: [
    ...
+   {
+     // typescript files
+     files: ['**/*.ts'],
+     plugins: ['@typescript-eslint'],
+     extends: ['plugin:@typescript-eslint/recommended'],
+     rules: {
+       '@typescript-eslint/explicit-module-boundary-types': 'error',
+     },
+   },
  ],
};
```

The first change swaps the standard `babel-eslint` parser for a custom one that can handle .ts files. The other two changes tell `eslint` that, in addition to the normal `eslint`, `prettier`, and `ember` rules, we want to also lint using the rules provided by `@typescript-eslint/recommended`.

Note: you can also now uninstall `babel-eslint` whose job is now handled by `@typescript-eslint/parser`.

```
npm uninstall babel-eslint
```

Bonus: if you'd like more strenuous type checking, you can make the following changes to make `eslint` aware of the type system:

```diff
// .eslintrc.js

module.exports = {
  ...
  overrides: [
    ...
    {
      // typescript files
      files: ['**/*.ts'],
+     parserOptions: {
+       project: true,
+       tsconfigRootDir: __dirname,
+     },
      plugins: ['@typescript-eslint'],
-     extends: ['plugin:@typescript-eslint/recommended'],
+     extends: [
+       'plugin:@typescript-eslint/recommended',
+       'plugin:@typescript-eslint/recommended-requiring-type-checking',
+     ],
      rules: {
        '@typescript-eslint/explicit-module-boundary-types': 'error',
      },
    },
  ],
};
```

And that's it! You should be able to execute `npm run lint` or `npm run lint:fix` and have you entire project linted.