Repository: dt-fe/number-precision Branch: master Commit: ccf201c3be42 Files: 11 Total size: 20.8 KB Directory structure: gitextract_gozwrrrm/ ├── .gitignore ├── .npmignore ├── .travis.yml ├── README.md ├── package.json ├── rollup.config.js ├── src/ │ └── index.ts ├── test/ │ └── index.test.ts ├── tsconfig.json ├── tsconfig.test.json └── tslint.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store *.log node_modules lib coverage logs build-test .rpt2_cache build/ .nyc_output/ ================================================ FILE: .npmignore ================================================ .DS_Store *.log examples test coverage ================================================ FILE: .travis.yml ================================================ dist: trusty language: node_js node_js: - 8 script: - npm test addons: firefox: "49.0" before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start ================================================ FILE: README.md ================================================ # number-precision [![npm version](https://badge.fury.io/js/number-precision.svg)](http://badge.fury.io/js/number-precision) [![Build Status](https://travis-ci.org/nefe/number-precision.svg)](https://travis-ci.org/nefe/number-precision) [![codecov](https://codecov.io/gh/nefe/number-precision/branch/master/graph/badge.svg)](https://codecov.io/gh/nefe/number-precision) Perform addition, subtraction, multiplication and division operations precisely using javascript ### Why ```js 0.1 + 0.2 = 0.30000000000000004 1.0 - 0.9 = 0.09999999999999998 0.105.toFixed(2) = 0.1 // not 0.11 ``` ### Install ``` npm install number-precision --save ``` ### Methods ```js NP.strip(num) // strip a number to nearest right number NP.plus(num1, num2, num3, ...) // addition, num + num2 + num3, two numbers is required at least. NP.minus(num1, num2, num3, ...) // subtraction, num1 - num2 - num3 NP.times(num1, num2, num3, ...) // multiplication, num1 * num2 * num3 NP.divide(num1, num2, num3, ...) // division, num1 / num2 / num3 NP.round(num, ratio) // round a number based on ratio ``` ### Usage ```js import NP from 'number-precision' NP.strip(0.09999999999999998); // = 0.1 NP.plus(0.1, 0.2); // = 0.3, not 0.30000000000000004 NP.plus(2.3, 2.4); // = 4.7, not 4.699999999999999 NP.minus(1.0, 0.9); // = 0.1, not 0.09999999999999998 NP.times(3, 0.3); // = 0.9, not 0.8999999999999999 NP.times(0.362, 100); // = 36.2, not 36.199999999999996 NP.divide(1.21, 1.1); // = 1.1, not 1.0999999999999999 NP.round(0.105, 2); // = 0.11, not 0.1 ``` PS: If you want to get rid of `XXX is beyond boundary when transfer to integer, the results may not be accurate`, use this at the beginning of your app to turn off boundary checking. ```js NP.enableBoundaryChecking(false); // default param is true ``` ### License MIT ================================================ FILE: package.json ================================================ { "name": "number-precision", "version": "1.6.0", "description": "Perform addition, subtraction, multiplication and division operations precisely using javascript", "main": "build/index.js", "module": "build/index.es.js", "types": "build/index.d.ts", "author": "cam song", "keywords": [ "number precision", "floating problem", "rounding error" ], "repository": { "type": "git", "url": "https://github.com/nefe/number-precision.git" }, "bugs": { "url": "https://github.com/nefe/number-precision/issues" }, "homepage": "https://github.com/nefe/number-precision", "scripts": { "build": "rollup -c", "watch": "rollup -cw", "test": "tsc -p tsconfig.test.json && nyc --reporter=lcov --reporter=text --reporter=json ava && rm -rf .nyc_output", "posttest": "codecov -f coverage/*.json -t 072762c4-c5bc-4393-bcd9-71eac9e7725b", "prepublish": "rm -rf build && tsc && npm run build", "tslint": "tslint ./src/**/*.ts --fix" }, "ava": { "files": [ "build-test/**/*.test.js" ] }, "pre-commit": [ "tslint" ], "devDependencies": { "ava": "^3.8.2", "braces": ">=2.3.1", "codecov": "^3.1.0", "nyc": "^15.0.1", "pre-commit": "^1.2.2", "rollup": "^0.52.2", "rollup-plugin-typescript": "^0.8.1", "rollup-plugin-typescript2": "^0.8.4", "rollup-watch": "^4.3.1", "tslint": "^5.8.0", "typescript": "^3.8.3" }, "license": "MIT" } ================================================ FILE: rollup.config.js ================================================ import typescript from 'rollup-plugin-typescript2' export default { input: './src/index.ts', output: [ { format: 'iife', name: 'NP', dest: './build/index.iife.js' }, { format: 'umd', name: 'NP', dest: './build/index.umd.js' }, { format: 'cjs', dest: './build/index.js' }, { format: 'es', dest: './build/index.es.js' } ], plugins: [typescript({cacheRoot: `${require('temp-dir')}/.rpt2_cache`})] } ================================================ FILE: src/index.ts ================================================ /** * @desc 解决浮动运算问题,避免小数点后产生多位数和计算精度损失。 * * 问题示例:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998 */ type NumberType = number | string; /** * Correct the given number to specifying significant digits. * * @param num The input number * @param precision An integer specifying the number of significant digits * * @example strip(0.09999999999999998) === 0.1 // true */ function strip(num: NumberType, precision = 15): number { return +parseFloat(Number(num).toPrecision(precision)); } /** * Return digits length of a number. * * @param num The input number */ function digitLength(num: NumberType): number { // Get digit length of e const eSplit = num.toString().split(/[eE]/); const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0); return len > 0 ? len : 0; } /** * Convert the given number to integer, support scientific notation. * The number will be scale up if it is decimal. * * @param num The input number */ function float2Fixed(num: NumberType): number { if (num.toString().indexOf('e') === -1) { return Number(num.toString().replace('.', '')); } const dLen = digitLength(num); return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num); } /** * Log a warning if the given number is out of bounds. * * @param num The input number */ function checkBoundary(num: number) { if (_boundaryCheckingState) { if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) { console.warn(`${num} is beyond boundary when transfer to integer, the results may not be accurate`); } } } /** * Create an operation to support rest params. * * @param operation The original operation */ function createOperation(operation: (n1: NumberType, n2: NumberType) => number): (...nums: NumberType[]) => number { return (...nums: NumberType[]) => { const [first, ...others] = nums; return others.reduce((prev, next) => operation(prev || 0, next || 0), first) as number; }; } /** * Accurate multiplication. * * @param nums The numbers to multiply */ const times = createOperation((num1, num2) => { const num1Changed = float2Fixed(num1); const num2Changed = float2Fixed(num2); const baseNum = digitLength(num1) + digitLength(num2); const leftValue = num1Changed * num2Changed; checkBoundary(leftValue); return leftValue / Math.pow(10, baseNum); }); /** * Accurate addition. * * @param nums The numbers to add */ const plus = createOperation((num1, num2) => { // 取最大的小数位 const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); // 把小数都转为整数然后再计算 return (times(num1, baseNum) + times(num2, baseNum)) / baseNum; }); /** * Accurate subtraction. * * @param nums The numbers to subtract */ const minus = createOperation((num1, num2) => { const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); return (times(num1, baseNum) - times(num2, baseNum)) / baseNum; }); /** * Accurate division. * * @param nums The numbers to divide */ const divide = createOperation((num1, num2) => { const num1Changed = float2Fixed(num1); const num2Changed = float2Fixed(num2); checkBoundary(num1Changed); checkBoundary(num2Changed); // fix: 类似 10 ** -4 为 0.00009999999999999999,strip 修正 return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1)))); }); /** * Accurate rounding method. * * @param num The number to round * @param decimal An integer specifying the decimal digits */ function round(num: NumberType, decimal: number): number { const base = Math.pow(10, decimal); let result = divide(Math.round(Math.abs(times(num, base))), base); if (num < 0 && result !== 0) { result = times(result, -1); } return result; } let _boundaryCheckingState = true; /** * Whether to check the bounds of number, default is enabled. * * @param flag The value to indicate whether is enabled */ function enableBoundaryChecking(flag = true) { _boundaryCheckingState = flag; } export { strip, plus, minus, times, divide, round, digitLength, float2Fixed, enableBoundaryChecking }; export default { strip, plus, minus, times, divide, round, digitLength, float2Fixed, enableBoundaryChecking, }; ================================================ FILE: test/index.test.ts ================================================ import test from 'ava'; import NP from '../src/index'; test('NP.strip can eliminate rounding errors', (t) => { t.true(NP.strip(0.09999999999999998) === 0.1); t.true(NP.strip(1.0000000000000001) === 1); t.true(NP.strip('0.09999999999999998') === 0.1); t.true(NP.strip('1.0000000000000001') === 1); }); test('NP.digitLength can do digitLength operation', (t) => { t.true(NP.digitLength(123.4567890123) === 10); t.true(NP.digitLength(1.23e-5) === 7); t.true(NP.digitLength(1.23E-5) === 7); t.true(NP.digitLength(1.233467e-5) === 11); t.true(NP.digitLength(123.45e-5) === 7); t.true(NP.digitLength(1.23e-10) === 12); t.true(NP.digitLength(1.23e1) === 1); t.true(NP.digitLength(1e20) === 0); t.true(NP.digitLength(1.12345e20) === 0); t.true(NP.digitLength(1.123e30) === 0); t.true(NP.digitLength(1.123e-100) === 103); t.true(NP.digitLength('1.23e-5') === 7); t.true(NP.digitLength('1.23E-5') === 7); t.true(NP.digitLength('1.233467e-5') === 11); t.true(NP.digitLength('123.45e-5') === 7); t.true(NP.digitLength('1.23e-10') === 12); t.true(NP.digitLength('1.23e1') === 1); t.true(NP.digitLength('1e20') === 0); t.true(NP.digitLength('1.12345e20') === 0); t.true(NP.digitLength('1.123e30') === 0); t.true(NP.digitLength('1.123e-100') === 103); }); test('NP.float2Fixed can change float to fixed', (t) => { t.true(NP.float2Fixed(1e-1) === 1); t.true(NP.float2Fixed(1e-6) === 1); t.true(NP.float2Fixed(1e-7) === 1); t.true(NP.float2Fixed(1e-13) === 1); t.true(NP.float2Fixed(1.123e30) === 1.123e30); t.true(NP.float2Fixed(1.6e-30) === 16); t.true(NP.float2Fixed(1.234567e-13) === 1234567); t.true(NP.float2Fixed(1.2345678912345e10) === 12345678912345); t.true(NP.float2Fixed(0.000000123456) === 123456); t.true(NP.float2Fixed(1.23456e-7) === 123456); t.true(NP.float2Fixed('1e-1') === 1); t.true(NP.float2Fixed('1e-6') === 1); t.true(NP.float2Fixed('1e-7') === 1); t.true(NP.float2Fixed('1e-13') === 1); t.true(NP.float2Fixed('1.123e30') === 1.123e30); t.true(NP.float2Fixed('1.6e-30') === 16); t.true(NP.float2Fixed('1.234567e-13') === 1234567); t.true(NP.float2Fixed('1.2345678912345e10') === 12345678912345); t.true(NP.float2Fixed('0.000000123456') === 123456); t.true(NP.float2Fixed('1.23456e-7') === 123456); }); test('NP.plus can do plus operation', (t) => { t.true(NP.plus(0.1, 0.2) === 0.3); t.true(NP.plus(2.3, 2.4) === 4.7); t.true(NP.plus(-1.6, -1) === -2.6); t.true(NP.plus(-2.0, 63) === 61); t.true(NP.plus(-3, 7) === 4); t.true(NP.plus(-221, 38) === -183); t.true(NP.plus(-1, 0) === -1); t.true(NP.plus(2.018, 0.001) === 2.019); t.true(NP.plus(1.3224e10, 1.3224e3) === 13224001322.4); t.true(NP.plus(1.6e-30, 1.6e-30) === 3.2e-30); t.true(NP.plus('0.1', '0.2') === 0.3); t.true(NP.plus('2.3', '2.4') === 4.7); t.true(NP.plus('-1.6', '-1') === -2.6); t.true(NP.plus('-2.0', '63') === 61); t.true(NP.plus('-3', '7') === 4); t.true(NP.plus('-221', '38') === -183); t.true(NP.plus('-1', '0') === -1); t.true(NP.plus('-1', '0', '2', '3', 4) === 8); t.true(NP.plus('2.018', '0.001') === 2.019); t.true(NP.plus('1.3224e10', '1.3224e3') === 13224001322.4); t.true(NP.plus('1.6e-30', '1.6e-30') === 3.2e-30); t.true(NP.plus(0.1, 0.2, 0.3) === 0.6); t.true(NP.plus('0.1', '0.2', '0.3') === 0.6); t.true(NP.plus(...new Array(500).fill(1)) === 500); }); test('NP.minus can do minus operation', (t) => { t.true(NP.minus(0.07, 0.01) === 0.06); t.true(NP.minus(0.7, 0.1) === 0.6); t.true(NP.minus(1.0, 0.9) === 0.1); t.true(NP.minus(1, 0) === 1); t.true(NP.minus(1, -0) === 1); t.true(NP.minus(-1, 0) === -1); t.true(NP.minus(-1, -0) === -1); t.true(NP.minus(1, 22) === -21); t.true(NP.minus(8893568.397103781249, -7.29674059550) === 8893575.693844376749); t.true(NP.minus(105468873, 0) === 105468873); t.true(NP.minus('0.07', '0.01') === 0.06); t.true(NP.minus('0.7', '0.1') === 0.6); t.true(NP.minus('1.0', '0.9') === 0.1); t.true(NP.minus('1', '0') === 1); t.true(NP.minus('1', '-0') === 1); t.true(NP.minus('-1', '0') === -1); t.true(NP.minus('-1', '-0') === -1); t.true(NP.minus('1', '22') === -21); t.true(NP.minus('8893568.397103781249', '-7.29674059550') === 8893575.693844376749); t.true(NP.minus('105468873', '0') === 105468873); t.true(NP.minus(1.23e5, 10) === 122990); t.true(NP.minus(1.23e-5, 1.0023) === -1.0022877); t.true(NP.minus(1.3224e10, 21) === 13223999979); t.true(NP.minus(1.3224e10, 1.3224e3) === 13223998677.6); t.true(NP.minus(1.7e-30, 0.1e-30) === 1.6e-30); t.true(NP.minus('1.23e5', '10') === 122990); t.true(NP.minus('1.23e-5', '1.0023') === -1.0022877); t.true(NP.minus('1.3224e10', '21') === 13223999979); t.true(NP.minus('1.3224e10', '1.3224e3') === 13223998677.6); t.true(NP.minus('1.7e-30', '0.1e-30') === 1.6e-30); t.true(NP.minus(6, 3, 2) === 1); t.true(NP.minus(6, 3, 2, 1, 2, 3) === -5); t.true(NP.minus('6', '3', '2') === 1); t.true(NP.minus('6', '3', '2', '1', '2', '3') === -5); t.true(NP.minus(500, ...new Array(500).fill(1)) === 0); }); test('NP.times can do times operation', (t) => { t.true(NP.times(0.07, 100) === 7); t.true(NP.times(0.7, 0.1) === 0.07); t.true(NP.times(3, 0.3) === 0.9); t.true(NP.times(118762317358.75, 1e-8) === 1187.6231735875); t.true(NP.times(0.362, 100) === 36.2); t.true(NP.times(1.1, 1.1) === 1.21); t.true(NP.times(2.018, 1000) === 2018); t.true(NP.times(5.2, -3.8461538461538462) === -20); t.true(NP.times(1.22, -1.639344262295082) === -2); t.true(NP.times(2.5, -0.92) === -2.3); t.true(NP.times(-2.2, 0.6363636363636364) === -1.4); t.true(NP.times('0.07', '100') === 7); t.true(NP.times('0.7', '0.1') === 0.07); t.true(NP.times('3', '0.3') === 0.9); t.true(NP.times('118762317358.75', '1e-8') === 1187.6231735875); t.true(NP.times('0.362', '100') === 36.2); t.true(NP.times('1.1', '1.1') === 1.21); t.true(NP.times('2.018', '1000') === 2018); t.true(NP.times('5.2', '-3.8461538461538462') === -20); t.true(NP.times('1.22', '-1.639344262295082') === -2); t.true(NP.times('2.5', '-0.92') === -2.3); t.true(NP.times('-2.2', '0.6363636363636364') === -1.4); // t.true(NP.times(-3, 2.3333333333333335) === 7); // t.true(NP.times(-0.076, -92.10526315789471) === 7); t.true(NP.times(8.0, -0.3625) === -2.9); t.true(NP.times(6.6, 0.30303030303030304) === 2); t.true(NP.times(10.0, -0.8) === -8); t.true(NP.times(-1.1, -7.272727272727273) === 8); t.true(NP.times('8.0', '-0.3625') === -2.9); t.true(NP.times('6.6', '0.30303030303030304') === 2); t.true(NP.times('10.0', '-0.8') === -8); t.true(NP.times('-1.1', '-7.272727272727273') === 8); t.true(NP.times(-1.23e4, 20) === -246000); t.true(NP.times(1.7e-30, 1.5e20) === 2.55e-10); t.true(NP.times('-1.23e4', '20') === -246000); t.true(NP.times('1.7e-30', '1.5e20') === 2.55e-10); t.true(NP.times(2, 2, 3) === 12); t.true(NP.times(2, 2, 3, 0.1) === 1.2); t.true(NP.times('2', '2', '3') === 12); t.true(NP.times('2', '2', '3', '0.1') === 1.2); t.true(NP.times(0.000000123456, 0.000000123456) === 1.5241383936e-14); t.true(NP.times(1.23456e-7, 1.23456e-7) === 1.5241383936e-14); t.true(NP.times('0.000000123456', '0.000000123456') === 1.5241383936e-14); t.true(NP.times('1.23456e-7', '1.23456e-7') === 1.5241383936e-14); t.true(NP.times(...new Array(500).fill(1)) === 1); }); test('NP.divide can do divide operation', (t) => { t.true(NP.divide(1.21, 1.1) === 1.1); t.true(NP.divide(4750.49269435, 4) === 1187.6231735875); t.true(NP.divide(0.9, 3) === 0.3); t.true(NP.divide(36.2, 0.362) === 100); t.true(NP.divide(-20, 5.2) === -3.8461538461538462); t.true(NP.divide(-2, 1.22) === -1.639344262295082); t.true(NP.divide(-2.3, 2.5) === -0.92); t.true(NP.divide(-1.4, -2.2) === 0.6363636363636364); t.true(NP.divide(7, -3) === -2.3333333333333335); t.true(NP.divide(7, -0.076) === -92.10526315789471); t.true(NP.divide(-2.9, 8.0) === -0.3625); t.true(NP.divide(2, 6.6) === 0.30303030303030304); t.true(NP.divide(-8, 10.0) === -0.8); t.true(NP.divide(8, -1.1) === -7.272727272727273); t.true(NP.divide('1.21', '1.1') === 1.1); t.true(NP.divide('4750.49269435', '4') === 1187.6231735875); t.true(NP.divide('0.9', '3') === 0.3); t.true(NP.divide('36.2', '0.362') === 100); t.true(NP.divide('-20', '5.2') === -3.8461538461538462); t.true(NP.divide('-2', '1.22') === -1.639344262295082); t.true(NP.divide('-2.3', '2.5') === -0.92); t.true(NP.divide('-1.4', '-2.2') === 0.6363636363636364); t.true(NP.divide('7', '-3') === -2.3333333333333335); t.true(NP.divide('7', '-0.076') === -92.10526315789471); t.true(NP.divide('-2.9', '8.0') === -0.3625); t.true(NP.divide('2', '6.6') === 0.30303030303030304); t.true(NP.divide('-8', '10.0') === -0.8); t.true(NP.divide('8', '-1.1') === -7.272727272727273); t.true(NP.divide(-1.23e4, 20) === -615); t.true(NP.divide(2.55e-10, 1.7e-30) === 1.5e20); t.true(NP.divide('-1.23e4', '20') === -615); t.true(NP.divide('2.55e-10', '1.7e-30') === 1.5e20); t.true(NP.divide(12, 3, 2) === 2); t.true(NP.divide(33.3333, 100) === 0.333333); t.true(NP.divide(83.42894732749, 100) === 0.8342894732749); t.true(NP.divide(1, 3) === 0.3333333333333333); t.true(NP.divide('12', '3', '2') === 2); t.true(NP.divide('33.3333', '100') === 0.333333); t.true(NP.divide('83.42894732749', '100') === 0.8342894732749); t.true(NP.divide('1', '3') === 0.3333333333333333); t.true(NP.divide(...new Array(500).fill(1)) === 1); t.true(NP.divide(1024, 4, 8, 2) === 16); }); test('NP.round can do round operation', (t) => { t.true(NP.round(0, 1) === 0); t.true(NP.round(0, 0) === 0); t.true(NP.round(0.7875, 3) === 0.788); t.true(NP.round(0.105, 2) === 0.11); t.true(NP.round(1, 1) === 1); t.true(NP.round(0.1049999999, 2) === 0.1); t.true(NP.round(0.105, 1) === 0.1); t.true(NP.round(1.335, 2) === 1.34); t.true(NP.round(1.35, 1) === 1.4); t.true(NP.round(12345.105, 2) === 12345.11); t.true(NP.round(0.0005, 2) === 0); t.true(NP.round(0.0005, 3) === 0.001); t.true(NP.round('0', 1) === 0); t.true(NP.round('0', 0) === 0); t.true(NP.round('0.7875', 3) === 0.788); t.true(NP.round('0.105', 2) === 0.11); t.true(NP.round('1', 1) === 1); t.true(NP.round('0.1049999999', 2) === 0.1); t.true(NP.round('0.105', 1) === 0.1); t.true(NP.round('1.335', 2) === 1.34); t.true(NP.round('1.35', 1) === 1.4); t.true(NP.round('12345.105', 2) === 12345.11); t.true(NP.round('0.0005', 2) === 0); t.true(NP.round('0.0005', 3) === 0.001); t.true(NP.round(1.2345e3, 3) === 1234.5); t.true(NP.round(1.2344e3, 3) === 1234.4); t.true(NP.round(1e3, 1) === 1000); t.true(NP.round('1.2345e3', 3) === 1234.5); t.true(NP.round('1.2344e3', 3) === 1234.4); t.true(NP.round('1e3', 1) === 1000); t.true(NP.round('-0.125', 2) === -0.13); t.true(NP.round('-0.001', 2) === 0.00); t.true(NP.round('-0.005', 2) === -0.01); t.true(NP.round('0.125', 2) === 0.13); t.true(NP.round('0.001', 2) === 0.00); t.true(NP.round('0.005', 2) === 0.01); t.true(NP.round(-0.125, 2) === -0.13); t.true(NP.round(-0.001, 2) === 0.00); t.true(NP.round(-0.005, 2) === -0.01); t.true(NP.round(0.125, 2) === 0.13); t.true(NP.round(0.001, 2) === 0.00); t.true(NP.round(0.005, 2) === 0.01); }); ================================================ FILE: tsconfig.json ================================================ { "compilerOptions": { "module": "commonjs", "strict": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "lib": [ "dom", "es5", "es6" ], "target": "es5", "outDir": "build", "sourceMap": true, "declaration": true }, "include": [ "src/*.ts" ], "exclude": [ "node_modules" ] } ================================================ FILE: tsconfig.test.json ================================================ { "compilerOptions": { "module": "commonjs", "strict": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "lib": [ "dom", "es5", "es6" ], "target": "es5", "outDir": "build-test", "sourceMap": true }, "exclude": [ "node_modules" ] } ================================================ FILE: tslint.json ================================================ { "extends": ["tslint:recommended"], "rules": { "arrow-parens": false, "arrow-return-shorthand": [true], "import-spacing": true, "interface-name": [false], "interface-over-type-literal": false, "linebreak-style": [true, "LF"], "max-classes-per-file": [false], "member-access": [false], "no-require-imports": true, "object-literal-sort-keys": false, "ordered-imports": [false], "no-console": false, "prefer-const": true, "quotemark": [true, "single", "jsx-double"], "space-before-function-paren": [true, { "anonymous": "always", "asyncArrow": "always", "constructor": "never", "method": "never", "named": "never" }], "variable-name": [ true, "ban-keywords", "check-format", "allow-pascal-case", "allow-leading-underscore" ] } }