Skip to content
This repository was archived by the owner on Jan 19, 2019. It is now read-only.

Commit

Permalink
[FEAT] [no-object-literal-type-assertion] Add rule (#225)
Browse files Browse the repository at this point in the history
  • Loading branch information
armano2 authored and bradzacher committed Dec 13, 2018
1 parent 3aec5a1 commit 1a97263
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ This guarantees 100% compatibility between the plugin and the parser.
* [`typescript/no-misused-new`](./docs/rules/no-misused-new.md) — Enforce valid definition of `new` and `constructor`. (`no-misused-new` from TSLint)
* [`typescript/no-namespace`](./docs/rules/no-namespace.md) — Disallow the use of custom TypeScript modules and namespaces
* [`typescript/no-non-null-assertion`](./docs/rules/no-non-null-assertion.md) — Disallows non-null assertions using the `!` postfix operator (`no-non-null-assertion` from TSLint)
* [`typescript/no-object-literal-type-assertion`](./docs/rules/no-object-literal-type-assertion.md) — Forbids an object literal to appear in a type assertion expression (`no-object-literal-type-assertion` from TSLint)
* [`typescript/no-parameter-properties`](./docs/rules/no-parameter-properties.md) — Disallow the use of parameter properties in class constructors. (`no-parameter-properties` from TSLint)
* [`typescript/no-triple-slash-reference`](./docs/rules/no-triple-slash-reference.md) — Disallow `/// <reference path="" />` comments (`no-reference` from TSLint)
* [`typescript/no-type-alias`](./docs/rules/no-type-alias.md) — Disallow the use of type aliases (`interface-over-type-literal` from TSLint)
Expand Down
30 changes: 30 additions & 0 deletions docs/rules/no-object-literal-type-assertion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Forbids an object literal to appear in a type assertion expression (no-object-literal-type-assertion)

Always prefer `const x: T = { ... };` to `const x = { ... } as T;`. Casting to `any` and `unknown` is still allowed.

## Rule Details

Examples of **incorrect** code for this rule.

```ts
const x = { ... } as T;
```

Examples of **correct** code for this rule.

```ts
const x: T = { ... };
const y = { ... } as any;
const z = { ... } as unknown;
```

## Options
```json
{
"typescript/no-object-literal-type-assertion": "error"
}
```

## Compatibility

* TSLint: [no-object-literal-type-assertion](https://palantir.github.io/tslint/rules/no-object-literal-type-assertion/)
71 changes: 71 additions & 0 deletions lib/rules/no-object-literal-type-assertion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* @fileoverview Forbids an object literal to appear in a type assertion expression
* @author Armano <https://github.com/armano2>
*/
"use strict";

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

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

module.exports = {
meta: {
docs: {
description:
"Forbids an object literal to appear in a type assertion expression",
extraDescription: [
util.tslintRule("no-object-literal-type-assertion"),
],
category: "TypeScript",
url: util.metaDocsUrl("no-object-literal-type-assertions"),
},
messages: {
unexpectedTypeAssertion:
"Type assertion on object literals is forbidden, use a type annotation instead.",
},
schema: [],
},
create(context) {
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------

/**
* Check whatever node should be reported
* @param {ASTNode} node the node to be evaluated.
* @returns {*} true or false
*/
function checkType(node) {
if (
node &&
node.type === "TSTypeAnnotation" &&
node.typeAnnotation
) {
switch (node.typeAnnotation.type) {
case "TSAnyKeyword":
case "TSUnknownKeyword":
return false;
default:
break;
}
}
return true;
}

return {
"TSTypeAssertionExpression, TSAsExpression"(node) {
if (
checkType(node.typeAnnotation) &&
node.expression.type === "ObjectExpression"
) {
context.report({
node,
messageId: "unexpectedTypeAssertion",
});
}
},
};
},
};
96 changes: 96 additions & 0 deletions tests/lib/rules/no-object-literal-type-assertion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* @fileoverview Forbids an object literal to appear in a type assertion expression
* @author Armano <https://github.com/armano2>
*/
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/no-object-literal-type-assertion"),
RuleTester = require("eslint").RuleTester;

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester({
parser: "typescript-eslint-parser",
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
ecmaFeatures: {
jsx: false,
},
},
});

ruleTester.run("no-object-literal-type-assertion", rule, {
valid: [
{
code: `<T> x;`,
},
{
code: `x as T;`,
},
{
code: `const foo = bar;`,
},
{
code: `const foo: baz = bar;`,
},
{
code: `const x: T = {};`,
},
{
code: `const foo = { bar: { } };`,
},
// Allow cast to 'any'
{
code: `const foo = {} as any;`,
},
{
code: `const foo = <any> {};`,
},
// Allow cast to 'unknown'
{
code: `const foo = {} as unknown;`,
},
{
code: `const foo = <unknown> {};`,
},
],
invalid: [
{
code: `<T> ({});`,
errors: [
{
messageId: "unexpectedTypeAssertion",
line: 1,
column: 1,
},
],
},
{
code: `({}) as T;`,
errors: [
{
messageId: "unexpectedTypeAssertion",
line: 1,
column: 1,
},
],
},
{
code: `const x = {} as T;`,
errors: [
{
messageId: "unexpectedTypeAssertion",
line: 1,
column: 11,
},
],
},
],
});

0 comments on commit 1a97263

Please sign in to comment.