Socket
Socket
Sign inDemoInstall

@typescript-eslint/eslint-plugin

Package Overview
Dependencies
Maintainers
1
Versions
3773
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@typescript-eslint/eslint-plugin - npm Package Compare versions

Comparing version 1.3.1-alpha.0 to 1.3.1-alpha.1

docs/rules/prefer-function-type.md

240

lib/rules/no-unnecessary-type-assertion.js

@@ -18,116 +18,2 @@ /**

/**
* Sometimes tuple types don't have ObjectFlags.Tuple set, like when they're being matched against an inferred type.
* So, in addition, check if there are integer properties 0..n and no other numeric keys
* @param {ts.ObjectType} type type
* @returns {boolean} true if type could be a tuple type
*/
function couldBeTupleType(type) {
const properties = type.getProperties();
if (properties.length === 0) {
return false;
}
let i = 0;
for (; i < properties.length; ++i) {
const name = properties[i].name;
if (String(i) !== name) {
if (i === 0) {
// if there are no integer properties, this is not a tuple
return false;
}
break;
}
}
for (; i < properties.length; ++i) {
if (String(+properties[i].name) === properties[i].name) {
return false; // if there are any other numeric properties, this is not a tuple
}
}
return true;
}
/**
*
* @param {Node} node node being linted
* @param {Context} context linting context
* @param {ts.TypeChecker} checker TypeScript typechecker
* @returns {void}
*/
function checkNonNullAssertion(node, context, checker) {
/**
* Corresponding TSNode is guaranteed to be in map
* @type {ts.NonNullExpression}
*/
const originalNode = context.parserServices.esTreeNodeToTSNodeMap.get(node);
const type = checker.getTypeAtLocation(originalNode.expression);
if (type === checker.getNonNullableType(type)) {
context.report({
node,
messageId: 'unnecessaryAssertion',
fix(fixer) {
return fixer.removeRange([
originalNode.expression.end,
originalNode.end
]);
}
});
}
}
/**
* @param {Node} node node being linted
* @param {Context} context linting context
* @param {ts.TypeChecker} checker TypeScript typechecker
* @returns {void}
*/
function verifyCast(node, context, checker) {
/**
* * Corresponding TSNode is guaranteed to be in map
* @type {ts.AssertionExpression}
*/
const originalNode = context.parserServices.esTreeNodeToTSNodeMap.get(node);
const options = context.options[0];
if (
options &&
options.typesToIgnore &&
options.typesToIgnore.indexOf(originalNode.type.getText()) !== -1
) {
return;
}
const castType = checker.getTypeAtLocation(originalNode);
if (
tsutils.isTypeFlagSet(castType, ts.TypeFlags.Literal) ||
(tsutils.isObjectType(castType) &&
(tsutils.isObjectFlagSet(castType, ts.ObjectFlags.Tuple) ||
couldBeTupleType(castType)))
) {
// It's not always safe to remove a cast to a literal type or tuple
// type, as those types are sometimes widened without the cast.
return;
}
const uncastType = checker.getTypeAtLocation(originalNode.expression);
if (uncastType === castType) {
context.report({
node,
messageId: 'unnecessaryAssertion',
fix(fixer) {
return originalNode.kind === ts.SyntaxKind.TypeAssertionExpression
? fixer.removeRange([
originalNode.getStart(),
originalNode.expression.getStart()
])
: fixer.removeRange([originalNode.expression.end, originalNode.end]);
}
});
}
}
/** @type {import("eslint").Rule.RuleModule} */

@@ -166,13 +52,133 @@ module.exports = {

create(context) {
const sourceCode = context.getSourceCode();
const checker = util.getParserServices(context).program.getTypeChecker();
/**
* Sometimes tuple types don't have ObjectFlags.Tuple set, like when they're being matched against an inferred type.
* So, in addition, check if there are integer properties 0..n and no other numeric keys
* @param {ts.ObjectType} type type
* @returns {boolean} true if type could be a tuple type
*/
function couldBeTupleType(type) {
const properties = type.getProperties();
if (properties.length === 0) {
return false;
}
let i = 0;
for (; i < properties.length; ++i) {
const name = properties[i].name;
if (String(i) !== name) {
if (i === 0) {
// if there are no integer properties, this is not a tuple
return false;
}
break;
}
}
for (; i < properties.length; ++i) {
if (String(+properties[i].name) === properties[i].name) {
return false; // if there are any other numeric properties, this is not a tuple
}
}
return true;
}
/**
* @param {Node} node node being linted
* @returns {void}
*/
function checkNonNullAssertion(node) {
/**
* Corresponding TSNode is guaranteed to be in map
* @type {ts.NonNullExpression}
*/
const originalNode = context.parserServices.esTreeNodeToTSNodeMap.get(
node
);
const type = checker.getTypeAtLocation(originalNode.expression);
if (type === checker.getNonNullableType(type)) {
context.report({
node,
messageId: 'unnecessaryAssertion',
fix(fixer) {
return fixer.removeRange([
originalNode.expression.end,
originalNode.end
]);
}
});
}
}
/**
* @param {Node} node node being linted
* @returns {void}
*/
function verifyCast(node) {
const options = context.options[0];
if (
options &&
options.typesToIgnore &&
options.typesToIgnore.indexOf(
sourceCode.getText(node.typeAnnotation)
) !== -1
) {
return;
}
/**
* Corresponding TSNode is guaranteed to be in map
* @type {ts.AssertionExpression}
*/
const originalNode = context.parserServices.esTreeNodeToTSNodeMap.get(
node
);
const castType = checker.getTypeAtLocation(originalNode);
if (
tsutils.isTypeFlagSet(castType, ts.TypeFlags.Literal) ||
(tsutils.isObjectType(castType) &&
(tsutils.isObjectFlagSet(castType, ts.ObjectFlags.Tuple) ||
couldBeTupleType(castType)))
) {
// It's not always safe to remove a cast to a literal type or tuple
// type, as those types are sometimes widened without the cast.
return;
}
const uncastType = checker.getTypeAtLocation(originalNode.expression);
if (uncastType === castType) {
context.report({
node,
messageId: 'unnecessaryAssertion',
fix(fixer) {
return originalNode.kind === ts.SyntaxKind.TypeAssertionExpression
? fixer.removeRange([
originalNode.getStart(),
originalNode.expression.getStart()
])
: fixer.removeRange([
originalNode.expression.end,
originalNode.end
]);
}
});
}
}
return {
TSNonNullExpression(node) {
checkNonNullAssertion(node, context, checker);
checkNonNullAssertion(node);
},
TSTypeAssertion(node) {
verifyCast(node, context, checker);
verifyCast(node);
},
TSAsExpression(node) {
verifyCast(node, context, checker);
verifyCast(node);
}

@@ -179,0 +185,0 @@ };

{
"name": "@typescript-eslint/eslint-plugin",
"version": "1.3.1-alpha.0+d178499",
"version": "1.3.1-alpha.1+b95c4cf",
"description": "TypeScript plugin for ESLint",

@@ -27,3 +27,3 @@ "keywords": [

"dependencies": {
"@typescript-eslint/parser": "1.3.1-alpha.0+d178499",
"@typescript-eslint/parser": "1.3.1-alpha.1+b95c4cf",
"requireindex": "^1.2.0",

@@ -40,3 +40,3 @@ "tsutils": "^3.7.0"

},
"gitHead": "d1784992902a41ffc76e917c6b2227e487c76671"
"gitHead": "b95c4cf803f42352976389494f604d0b94bbf644"
}

@@ -147,2 +147,3 @@ <h1 align="center">ESLint Plugin TypeScript</h1>

| [`@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-function-type`](./docs/rules/prefer-function-type.md) | Use function types instead of interfaces with call signatures (`callable-types` from TSLint) | | :wrench: |
| [`@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: |

@@ -149,0 +150,0 @@ | [`@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: |

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc