├── .circleci └── config.yml ├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── package.json ├── tests └── App.tsx ├── tsconfig.base.json └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | # specify the version you desire here 10 | - image: circleci/node:16.13 11 | 12 | # Specify service dependencies here if necessary 13 | # CircleCI maintains a library of pre-built images 14 | # documented at https://circleci.com/docs/2.0/circleci-images/ 15 | # - image: circleci/mongo:3.4.4 16 | 17 | working_directory: ~/repo 18 | 19 | steps: 20 | - checkout 21 | 22 | # Download and cache dependencies 23 | - restore_cache: 24 | keys: 25 | - v1-dependencies-{{ checksum "package.json" }} 26 | # fallback to using the latest cache if no exact match is found 27 | - v1-dependencies- 28 | 29 | - run: yarn install 30 | 31 | - save_cache: 32 | paths: 33 | - node_modules 34 | key: v1-dependencies-{{ checksum "package.json" }} 35 | 36 | # run tests! 37 | - run: yarn test 38 | 39 | - deploy: 40 | name: Expo Deployment 41 | command: | 42 | if [ "${CIRCLE_BRANCH}" == "master" ]; then 43 | yarn semantic-release 44 | fi 45 | 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 William Candillon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eslint-config-react-native-wcandillon 2 | My ESLint and TypeScript configuration for React Native. 3 | 4 | [![CircleCI](https://circleci.com/gh/wcandillon/eslint-config-react-native-wcandillon.svg?style=svg)](https://circleci.com/gh/wcandillon/eslint-config-react-native-wcandillon) 5 | [![npm version](https://badge.fury.io/js/eslint-config-react-native-wcandillon.svg)](https://badge.fury.io/js/eslint-config-react-native-wcandillon) 6 | 7 | ## Usage 8 | 9 | ```sh 10 | # you also need eslint if not installed already: yarn add eslint --dev 11 | yarn add eslint-config-react-native-wcandillon --dev 12 | ``` 13 | 14 | In `.eslintrc`: 15 | 16 | ```json 17 | { 18 | "extends": "react-native-wcandillon", 19 | } 20 | ``` 21 | 22 | In `tsconfig.json` (if you want to use my base TS configuration): 23 | 24 | ```json 25 | { 26 | "extends": "eslint-config-react-native-wcandillon/tsconfig.base" 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": ["import"], 3 | "extends": [ 4 | "plugin:@typescript-eslint/recommended", 5 | "@react-native-community", 6 | "prettier", 7 | "plugin:import/typescript", 8 | ], 9 | "rules": { 10 | "quotes": [ 11 | "error", 12 | "double", 13 | { 14 | "avoidEscape": true 15 | } 16 | ], 17 | "max-len": [ 18 | "error", 19 | 120 20 | ], 21 | "@typescript-eslint/ban-ts-comment": 2, 22 | "@typescript-eslint/no-explicit-any": 2, 23 | "@typescript-eslint/explicit-module-boundary-types": 0, 24 | "@typescript-eslint/consistent-type-imports": 2, 25 | "react/jsx-filename-extension": ["error", { "extensions": [".tsx"] }], 26 | "react/jsx-uses-react": "off", 27 | "react/react-in-jsx-scope": "off", 28 | "react-native/no-unused-styles": 2, 29 | "react-native/split-platform-components": 2, 30 | "react-native/no-inline-styles": 0, 31 | "react-native/no-color-literals": 0, 32 | "react-native/no-raw-text": 0, 33 | "import/no-extraneous-dependencies": 2, 34 | "import/extensions": ["error", "never", { "svg": "always" }], 35 | "import/order": ["error", {"newlines-between": "always"}], 36 | "import/no-duplicates": 2, 37 | "import/no-useless-path-segments": 2, 38 | "import/no-cycle": [2, { "ignoreExternal": true }], 39 | "import/prefer-default-export": 0, 40 | "import/named": 0, 41 | "import/namespace": 0, 42 | "import/default": 0, 43 | "import/no-named-as-default-member": 0, 44 | "import/no-named-as-default": 0, 45 | "import/no-unused-modules": 0, 46 | "import/no-deprecated": 0, 47 | "@typescript-eslint/indent": 0, 48 | "import/no-anonymous-default-export": 2, 49 | "import/no-default-export": 2, 50 | "react-hooks/rules-of-hooks": 2, 51 | "react-hooks/exhaustive-deps": ["error", { "additionalHooks": "(useMemoOne)" }], 52 | "jest/no-identical-title": 2, 53 | "jest/valid-expect": 2, 54 | "camelcase": 2, 55 | "prefer-destructuring": 2, 56 | "no-nested-ternary": 2, 57 | "comma-dangle": 0, 58 | "@typescript-eslint/no-unused-vars": "off", 59 | "@typescript-eslint/no-shadow": ["error"], 60 | "no-shadow": "off", 61 | "curly": "error" 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-react-native-wcandillon", 3 | "version": "0.0.0-development", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "eslint -c index.js tests/*.tsx --fix", 8 | "semantic-release": "semantic-release" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/wcandillon/eslint-config-react-native-wcandillon.git" 13 | }, 14 | "author": "William Candillon ", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/wcandillon/eslint-config-react-native-wcandillon/issues" 18 | }, 19 | "homepage": "https://github.com/wcandillon/eslint-config-react-native-wcandillon#readme", 20 | "devDependencies": { 21 | "eslint": "8.37.0", 22 | "semantic-release": "^19.0.3", 23 | "semantic-release-cli": "^5.4.3" 24 | }, 25 | "dependencies": { 26 | "@react-native-community/eslint-config": "3.2.0", 27 | "@typescript-eslint/eslint-plugin": "6.10.0", 28 | "@typescript-eslint/parser": "6.10.0", 29 | "eslint-plugin-import": "2.27.5", 30 | "prettier": "2.8.7", 31 | "typescript": "5.0.3" 32 | }, 33 | "resolutions": { 34 | "@typescript-eslint/eslint-plugin": "6.10.0", 35 | "@typescript-eslint/parser": "6.10.0", 36 | "eslint-plugin-flowtype": "8.0.3" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | type RGB = readonly [red: number, green: number, blue: number]; 4 | 5 | type Color = { value: RGB | string }; 6 | 7 | const myColor = { value: "red" } satisfies Color; // works 8 | 9 | myColor.value.toUpperCase(); // valid operation as myColor is a string 10 | 11 | const white = "#fff"; 12 | const styles = StyleSheet.create({ 13 | container: { 14 | flex: 1, 15 | backgroundColor: white, 16 | alignItems: "center", 17 | justifyContent: "center", 18 | }, 19 | }); 20 | 21 | export const App = () => ( 22 | 23 | Open up App.js to start working on your app! 24 | 25 | ); 26 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "wcandillon's config", 4 | "compilerOptions": { 5 | "target": "esnext", 6 | "lib": [ 7 | "dom", 8 | "es2019" 9 | ], 10 | "allowJs": true, 11 | "skipLibCheck": true, 12 | "noEmit": true, 13 | "allowSyntheticDefaultImports": true, 14 | "resolveJsonModule": true, 15 | "esModuleInterop": true, 16 | "moduleResolution": "node", 17 | "jsx": "react-native", 18 | "strict": true, 19 | "noUnusedLocals": true /* Report errors on unused locals. */, 20 | "noUnusedParameters": true /* Report errors on unused parameters. */, 21 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 22 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 23 | "noUncheckedIndexedAccess": false, /* Include 'undefined' in index signature results */ 24 | "allowUnreachableCode": false, 25 | "allowUnusedLabels": false, 26 | "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 27 | "strictNullChecks": true, /* Enable strict null checks. */ 28 | "strictFunctionTypes": true, /* Enable strict checking of function types. */ 29 | "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 30 | "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 31 | "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 32 | "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */ 33 | }, 34 | "exclude": ["node_modules", "babel.config.js", "metro.config.js", "jest.config.js"] 35 | } 36 | --------------------------------------------------------------------------------