forked from bradzacher/eslint-plugin-typescript
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix: camelcase properties in interfaces (fixes bradzacher#177)
- Loading branch information
1 parent
e936298
commit bdf759a
Showing
4 changed files
with
295 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
# Enforce camelCase naming convention (camelcase) | ||
|
||
When it comes to naming variables, style guides generally fall into one of two | ||
camps: camelcase (`variableName`) and underscores (`variable_name`). This rule | ||
focuses on using the camelcase approach. If your style guide calls for | ||
camelCasing your variable names, then this rule is for you! | ||
|
||
## Rule Details | ||
|
||
This rule looks for any underscores (`_`) located within the source code. | ||
It ignores leading and trailing underscores and only checks those in the middle | ||
of a variable name. If ESLint decides that the variable is a constant | ||
(all uppercase), then no warning will be thrown. Otherwise, a warning will be | ||
thrown. This rule only flags definitions and assignments but not function calls. | ||
In case of ES6 `import` statements, this rule only targets the name of the | ||
variable that will be imported into the local module scope. | ||
|
||
***This rule was taken from the ESLint core rule `camelcase`.*** | ||
***Available options and test cases may vary depending on the version of ESLint installed in the system.*** | ||
|
||
## Options | ||
|
||
This rule has an object option: | ||
|
||
* `"properties": "always"` (default) enforces camelcase style for property names | ||
* `"properties": "never"` does not check property names | ||
* `"ignoreDestructuring": false` (default) enforces camelcase style for destructured identifiers | ||
* `"ignoreDestructuring": true` does not check destructured identifiers | ||
* `allow` (`string[]`) list of properties to accept. Accept regex. | ||
|
||
### properties: "always" | ||
|
||
Examples of **incorrect** code for this rule with the default `{ "properties": "always" }` option: | ||
|
||
```js | ||
/*eslint camelcase: "error"*/ | ||
|
||
import { no_camelcased } from "external-module" | ||
|
||
var my_favorite_color = "#112C85"; | ||
|
||
function do_something() { | ||
// ... | ||
} | ||
|
||
obj.do_something = function() { | ||
// ... | ||
}; | ||
|
||
function foo({ no_camelcased }) { | ||
// ... | ||
}; | ||
|
||
function foo({ isCamelcased: no_camelcased }) { | ||
// ... | ||
} | ||
|
||
function foo({ no_camelcased = 'default value' }) { | ||
// ... | ||
}; | ||
|
||
var obj = { | ||
my_pref: 1 | ||
}; | ||
|
||
var { category_id = 1 } = query; | ||
|
||
var { foo: no_camelcased } = bar; | ||
|
||
var { foo: bar_baz = 1 } = quz; | ||
``` | ||
|
||
Examples of **correct** code for this rule with the default `{ "properties": "always" }` option: | ||
|
||
```js | ||
/*eslint camelcase: "error"*/ | ||
|
||
import { no_camelcased as camelCased } from "external-module"; | ||
|
||
var myFavoriteColor = "#112C85"; | ||
var _myFavoriteColor = "#112C85"; | ||
var myFavoriteColor_ = "#112C85"; | ||
var MY_FAVORITE_COLOR = "#112C85"; | ||
var foo = bar.baz_boom; | ||
var foo = { qux: bar.baz_boom }; | ||
|
||
obj.do_something(); | ||
do_something(); | ||
new do_something(); | ||
|
||
var { category_id: category } = query; | ||
|
||
function foo({ isCamelCased }) { | ||
// ... | ||
}; | ||
|
||
function foo({ isCamelCased: isAlsoCamelCased }) { | ||
// ... | ||
} | ||
|
||
function foo({ isCamelCased = 'default value' }) { | ||
// ... | ||
}; | ||
|
||
var { categoryId = 1 } = query; | ||
|
||
var { foo: isCamelCased } = bar; | ||
|
||
var { foo: isCamelCased = 1 } = quz; | ||
|
||
``` | ||
|
||
### properties: "never" | ||
|
||
Examples of **correct** code for this rule with the `{ "properties": "never" }` option: | ||
|
||
```js | ||
/*eslint camelcase: ["error", {properties: "never"}]*/ | ||
|
||
var obj = { | ||
my_pref: 1 | ||
}; | ||
``` | ||
|
||
### ignoreDestructuring: false | ||
|
||
Examples of **incorrect** code for this rule with the default `{ "ignoreDestructuring": false }` option: | ||
|
||
```js | ||
/*eslint camelcase: "error"*/ | ||
|
||
var { category_id } = query; | ||
|
||
var { category_id = 1 } = query; | ||
|
||
var { category_id: category_id } = query; | ||
|
||
var { category_id: category_alias } = query; | ||
|
||
var { category_id: categoryId, ...other_props } = query; | ||
``` | ||
|
||
### ignoreDestructuring: true | ||
|
||
Examples of **incorrect** code for this rule with the `{ "ignoreDestructuring": true }` option: | ||
|
||
```js | ||
/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/ | ||
|
||
var { category_id: category_alias } = query; | ||
|
||
var { category_id, ...other_props } = query; | ||
``` | ||
|
||
Examples of **correct** code for this rule with the `{ "ignoreDestructuring": true }` option: | ||
|
||
```js | ||
/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/ | ||
|
||
var { category_id } = query; | ||
|
||
var { category_id = 1 } = query; | ||
|
||
var { category_id: category_id } = query; | ||
``` | ||
|
||
## allow | ||
|
||
Examples of **correct** code for this rule with the `allow` option: | ||
|
||
```js | ||
/*eslint camelcase: ["error", {allow: ["UNSAFE_componentWillMount"]}]*/ | ||
|
||
function UNSAFE_componentWillMount() { | ||
// ... | ||
} | ||
``` | ||
|
||
```js | ||
/*eslint camelcase: ["error", {allow: ["^UNSAFE_"]}]*/ | ||
|
||
function UNSAFE_componentWillMount() { | ||
// ... | ||
} | ||
|
||
function UNSAFE_componentWillMount() { | ||
// ... | ||
} | ||
``` | ||
|
||
## When Not To Use It | ||
|
||
If you have established coding standards using a different naming convention (separating words with underscores), turn this rule off. | ||
|
||
<sup>Taken with ❤️ [from ESLint core](https://github.com/eslint/eslint/blob/master/docs/rules/camelcase.md)</sup> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/** | ||
* @fileoverview Rule to flag non-camelcased identifiers | ||
* @author Patricio Trevino | ||
*/ | ||
"use strict"; | ||
|
||
const baseRule = require("eslint/lib/rules/camelcase"); | ||
|
||
//------------------------------------------------------------------------------ | ||
// Rule Definition | ||
//------------------------------------------------------------------------------ | ||
|
||
module.exports = { | ||
meta: Object.assign({}, baseRule.meta, { | ||
docs: { | ||
description: "Enforce camelCase naming convention" | ||
} | ||
}), | ||
|
||
create(context) { | ||
const rules = baseRule.create(context); | ||
|
||
const options = context.options[0] || {}; | ||
let properties = options.properties || ""; | ||
const allow = options.allow || []; | ||
|
||
if (properties !== "always" && properties !== "never") { | ||
properties = "always"; | ||
} | ||
|
||
/** | ||
* Checks if a string contains an underscore and isn't all upper-case | ||
* @param {string} name The string to check. | ||
* @returns {boolean} if the string is underscored | ||
* @private | ||
*/ | ||
function isUnderscored(name) { | ||
// if there's an underscore, it might be A_CONSTANT, which is okay | ||
return name.indexOf("_") > -1 && name !== name.toUpperCase(); | ||
} | ||
|
||
/** | ||
* Checks if a string match the ignore list | ||
* @param {string} name The string to check. | ||
* @returns {boolean} if the string is ignored | ||
* @private | ||
*/ | ||
function isAllowed(name) { | ||
return ( | ||
allow.findIndex( | ||
entry => name === entry || name.match(new RegExp(entry)) | ||
) !== -1 | ||
); | ||
} | ||
|
||
return { | ||
Identifier(node) { | ||
/* | ||
* Leading and trailing underscores are commonly used to flag | ||
* private/protected identifiers, strip them | ||
*/ | ||
const name = node.name.replace(/^_+|_+$/g, ""); | ||
|
||
// First, we ignore the node if it match the ignore list | ||
if (isAllowed(name)) { | ||
return; | ||
} | ||
|
||
// Check TypeScript specific nodes | ||
if (node.parent && node.parent.type === "TSPropertySignature") { | ||
if (properties === "always" && isUnderscored(name)) { | ||
context.report({ | ||
node, | ||
messageId: "notCamelCase", | ||
data: { name: node.name } | ||
}); | ||
} | ||
|
||
return; | ||
} | ||
|
||
// Let the base rule deal with the rest | ||
// eslint-disable-next-line new-cap | ||
rules.Identifier(node); | ||
} | ||
}; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters