diff --git a/README.md b/README.md index b2399eb7..ce48d79c 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,14 @@ Just **focus** on coding. - [React](#react) - [Flow](#flow) - [Flow with React](#flow-with-react) + - [TypeScript](#typescript) + - [TypeScript with React](#typescript-with-react) - [Vue](#vue) - [Node.js](#nodejs) - [Existing codebase setup](#existing-codebase-setup) - [Setup autofix in IDE](#setup-autofix-in-ide) - [Ignoring files](#ignoring-files) -- [Contibuting](#contibuting) +- [Contributing](#contributing) - [Test](#test) - [Release](#release) @@ -158,6 +160,58 @@ module.exports = { } ``` +### TypeScript + +**terminal** +```sh +yarn add @typescript-eslint/parser @typescript-eslint/eslint-plugin typescript --dev +``` + +**.eslintrc.js** +```js +module.exports = { + extends: 'algolia/typescript' +}; +``` + +**package.json** +```json +{ + "scripts": { + "test": "npm run lint", + "lint": "eslint --ext .js,.ts,.tsx .", + "lint:fix": "npm run lint -- --fix" + } +} +``` + +### TypeScript with React + +**terminal** +```sh +yarn add @typescript-eslint/parser @typescript-eslint/eslint-plugin typescript eslint-plugin-react --dev +``` + +**.eslintrc.js** +```js +module.exports = { + extends: ['algolia/react', 'algolia/typescript'] +}; +``` +**Note**: Be sure to put the `algolia/typescript` configuration last so the parser is properly set for TypeScript files. + +**package.json** +```json +{ + "scripts": { + "test": "npm run lint", + "lint": "eslint --ext .js,.ts,.tsx .", + "lint:fix": "npm run lint -- --fix" + } +} +``` + + ### Vue **terminal** @@ -244,7 +298,7 @@ Also activate "Lint HTML files" when dealing with `.vue` components. See "Ignoring Files and Directories" on [ESLint website](http://eslint.org/docs/user-guide/configuring.html#ignoring-files-and-directories). -## Contibuting +## Contributing ### Test diff --git a/rules/typescript.js b/rules/typescript.js new file mode 100644 index 00000000..61f6a891 --- /dev/null +++ b/rules/typescript.js @@ -0,0 +1,74 @@ +// eslint-disable-next-line import/no-commonjs +module.exports = { + plugins: ['@typescript-eslint'], + rules: { + '@typescript-eslint/adjacent-overload-signatures': ['error'], + '@typescript-eslint/array-type': ['error', 'array-simple'], + '@typescript-eslint/ban-types': ['error'], + '@typescript-eslint/ban-ts-ignore': ['off'], + '@typescript-eslint/camelcase': ['error'], + '@typescript-eslint/class-name-casing': ['error'], + '@typescript-eslint/explicit-function-return-type': [ + 'error', + { + allowExpressions: true, + allowTypedFunctionExpressions: true, + }, + ], + '@typescript-eslint/explicit-member-accessibility': ['error'], + '@typescript-eslint/generic-type-naming': ['error', '^T[A-Z][a-zA-Z]+$'], + '@typescript-eslint/indent': ['off'], + '@typescript-eslint/interface-name-prefix': ['error', 'never'], + '@typescript-eslint/member-delimiter-style': ['off'], + '@typescript-eslint/member-naming': ['off'], + '@typescript-eslint/member-ordering': [ + 'error', + { + default: ['static-field'], + }, + ], + '@typescript-eslint/no-angle-bracket-type-assertion': ['error'], + '@typescript-eslint/no-array-constructor': ['error'], + '@typescript-eslint/no-empty-interface': ['error'], + '@typescript-eslint/no-explicit-any': ['off'], + '@typescript-eslint/no-extraneous-class': ['off'], + '@typescript-eslint/no-for-in-array': ['off'], + '@typescript-eslint/no-inferrable-types': ['off'], + '@typescript-eslint/no-misused-new': ['error'], + '@typescript-eslint/no-namespace': ['error'], + '@typescript-eslint/no-non-null-assertion': ['off'], + '@typescript-eslint/no-object-literal-type-assertion': ['off'], + '@typescript-eslint/no-parameter-properties': ['off'], + '@typescript-eslint/no-require-imports': ['off'], + '@typescript-eslint/no-this-alias': ['off'], + '@typescript-eslint/no-triple-slash-reference': ['error'], + '@typescript-eslint/no-type-alias': ['off'], + '@typescript-eslint/no-unnecessary-qualifier': ['off'], + '@typescript-eslint/no-unnecessary-type-assertion': ['off'], + '@typescript-eslint/no-unused-vars': [ + 'error', + { + ignoreRestSiblings: true, + }, + ], + '@typescript-eslint/no-use-before-define': ['error', { functions: false }], + '@typescript-eslint/no-useless-constructor': ['error'], + '@typescript-eslint/no-var-requires': ['off'], + '@typescript-eslint/prefer-for-of': ['off'], + '@typescript-eslint/prefer-function-type': ['error'], + '@typescript-eslint/prefer-interface': ['off'], + '@typescript-eslint/prefer-namespace-keyword': ['error'], + '@typescript-eslint/promise-function-async': ['off'], + '@typescript-eslint/restrict-plus-operands': ['off'], + '@typescript-eslint/type-annotation-spacing': ['error'], + '@typescript-eslint/unbound-method': ['off'], + '@typescript-eslint/unified-signatures': ['error'], + + // Disable rules superset by @typescript-eslint + 'no-unused-vars': ['off'], + 'no-use-before-define': ['off'], + camelcase: ['off'], + 'no-array-constructor': ['off'], + 'no-useless-constructor': ['off'], + }, +}; diff --git a/typescript.js b/typescript.js new file mode 100644 index 00000000..38764d67 --- /dev/null +++ b/typescript.js @@ -0,0 +1,17 @@ +// eslint-disable-next-line import/no-commonjs +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + impliedStrict: true, + jsx: true, + }, + }, + extends: [ + './base.js', + './rules/typescript.js', + 'prettier/@typescript-eslint', + ], +};