Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat(eslint-plugin): add new rule restrict-plus-operands#70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
JamesHenry merged 9 commits intotypescript-eslint:masterfromarmano2:restrict-plus-operands
Jan 22, 2019
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletionspackages/eslint-plugin/README.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,6 +93,7 @@ You can also enable all the recommended rules at once. Add `plugin:@typescript-e
| [`@typescript-eslint/no-var-requires`](./docs/rules/no-var-requires.md) | Disallows the use of require statements except in import statements (`no-var-requires` from TSLint) | :heavy_check_mark: | |
| [`@typescript-eslint/prefer-interface`](./docs/rules/prefer-interface.md) | Prefer an interface declaration over a type literal (type T = { ... }) (`interface-over-type-literal` from TSLint) | :heavy_check_mark: | :wrench: |
| [`@typescript-eslint/prefer-namespace-keyword`](./docs/rules/prefer-namespace-keyword.md) | Require the use of the `namespace` keyword instead of the `module` keyword to declare custom TypeScript modules. (`no-internal-module` from TSLint) | :heavy_check_mark: | :wrench: |
| [`@typescript-eslint/restrict-plus-operands`](./docs/rules/restrict-plus-operands.md) | When adding two variables, operands must both be of type number or of type string. (`restrict-plus-operands` from TSLint) | | |
| [`@typescript-eslint/type-annotation-spacing`](./docs/rules/type-annotation-spacing.md) | Require consistent spacing around type annotations (`typedef-whitespace` from TSLint) | :heavy_check_mark: | :wrench: |

<!-- end rule list -->
25 changes: 25 additions & 0 deletionspackages/eslint-plugin/docs/rules/restrict-plus-operands.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
# When adding two variables, operands must both be of type number or of type string. (restrict-plus-operands)

Examples of **correct** code:

```ts
var foo = parseInt('5.5', 10) + 10;
```

Examples of **incorrect** code:

```ts
var foo = '5.5' + 5;
```

## Options

```json
{
"@typescript-eslint/restrict-plus-operands": "error"
}
```

## Compatibility

- TSLint: [restrict-plus-operands](https://palantir.github.io/tslint/rules/restrict-plus-operands/)
104 changes: 104 additions & 0 deletionspackages/eslint-plugin/lib/rules/restrict-plus-operands.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
/**
* @fileoverview When adding two variables, operands must both be of type number or of type string.
* @author James Henry
* @author Armano <https://github.com/armano2>
*/
'use strict';

const util = require('../util');

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = {
meta: {
type: 'problem',
docs: {
description:
'When adding two variables, operands must both be of type number or of type string.',
extraDescription: [util.tslintRule('restrict-plus-operands')],
category: 'TypeScript',
url: util.metaDocsUrl('restrict-plus-operands')
},
messages: {
notNumbers:
"Operands of '+' operation must either be both strings or both numbers.",
notStrings:
"Operands of '+' operation must either be both strings or both numbers. Consider using a template literal."
},
schema: []
},

create(context) {
const service = util.getParserServices(context);

const typeChecker = service.program.getTypeChecker();

/**
* Helper function to get base type of node
* @param {ts.Type} type type to be evaluated
* @returns {*} string, number or invalid
*/
function getBaseTypeOfLiteralType(type) {
if (type.isNumberLiteral()) {
return 'number';
}
if (type.isStringLiteral()) {
return 'string';
}
if (type.isUnion()) {
const types = type.types.map(getBaseTypeOfLiteralType);

return types.every(value => value === types[0]) ? types[0] : 'invalid';
}

const stringType = typeChecker.typeToString(type);

if (stringType === 'number' || stringType === 'string') {
return stringType;
}
return 'invalid';
}

/**
* Helper function to get base type of node
* @param {ASTNode} node the node to be evaluated.
* @returns {*} string, number or invalid
*/
function getNodeType(node) {
const tsNode = service.esTreeNodeToTSNodeMap.get(node);
const type = typeChecker.getTypeAtLocation(tsNode);

return getBaseTypeOfLiteralType(type);
}

//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
return {
"BinaryExpression[operator='+']"(node) {
const leftType = getNodeType(node.left);
const rightType = getNodeType(node.right);

if (
leftType === 'invalid' ||
rightType === 'invalid' ||
leftType !== rightType
) {
if (leftType === 'string' || rightType === 'string') {
context.report({
node,
messageId: 'notStrings'
});
} else {
context.report({
node,
messageId: 'notNumbers'
});
}
}
}
};
}
};
9 changes: 9 additions & 0 deletionspackages/eslint-plugin/tests/fixtures/tsconfig.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"lib": ["es2015", "es2017"]
}
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp