Skip to content

Commit

Permalink
feat: add no-computed-public-class-fields rule
Browse files Browse the repository at this point in the history
  • Loading branch information
keithamus committed Sep 20, 2019
1 parent b97ee53 commit d8ce1cb
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
41 changes: 41 additions & 0 deletions docs/no-computed-class-fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# no-computed-class-fields

This prevents the use of computed properties as Class Fields

```js
const computed = 'bar'
class Foo {
[computed] = 1
}

class Foo {
static [computed] = 1
}
```

These will not be allowed because Chrome 72, while supporting class fields, does not support computed properties in class fields.

## What is the Fix?

Either make the property non-computed, or you can move these assignments to within the class constructor function for instance properties, or modify the class for static ones:

```js
const computed = 'bar'
class Foo {
constructor() {
Object.defineProperty(this, computed, { configurable: true, enumerable: true, writable: true, value: 1 })
}
}

class Foo {
constructor() {
this[computed] = 1
}
}

// Static
Object.defineProperty(Foo, computed, { configurable: true, enumerable: true, writable: true, value: 1 })
Foo[computed] = 1
```

This can be safely disabled if you intend to compile code with the `@babel/plugin-proposal-class-properties` Babel plugin.
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ createRule('no-optional-catch', 'edge > 0, safari > 0, firefox < 58, chrome < 66
createRule('no-numeric-separators', 'edge > 0, safari < 13, firefox < 68, chrome < 75', 'disallow use of numeric seperators like 1_000_000')
createRule('no-public-static-class-fields', 'edge > 0, safari > 0, firefox > 0, chrome < 72', 'disallow public static class fields like foo = 1')
createRule('no-public-instance-class-fields', 'edge > 0, safari > 0, firefox < 69, chrome < 72', 'disallow public class fields like foo = 1')
createRule('no-computed-public-static-class-fields', 'edge > 0, safari > 0, firefox < 69, chrome < 74', 'disallow computed public static or instance class fields like [foo] = 1')
createRule('no-private-class-fields', 'edge > 0, safari > 0, firefox > 0, chrome < 74', 'disallow private class fields like #foo = 1')
createRule('no-do-expression', 'edge > 0, safari > 0, firefox > 0, chrome > 0', 'disallow "do" expressions')
createRule('no-bind-operator', 'edge > 0, safari > 0, firefox > 0, chrome > 0', 'disallow the :: bind operator')
Expand Down
6 changes: 6 additions & 0 deletions lib/rules/no-computed-public-class-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = (context, badBrowser) => ({
// Ignore type annotations that don't assign
'ClassProperty[computed=true]:not([typeAnnotation]:not([value]))'(node) {
context.report(node, `Computed Class Fields are not supported in ${badBrowser}`)
}
})
58 changes: 58 additions & 0 deletions test/no-computed-public-class-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
var rule = require('../lib/rules/no-computed-public-class-fields')
var RuleTester = require('eslint').RuleTester

var ruleTester = new RuleTester({parser: 'babel-eslint', parserOptions: {ecmaVersion: 2018}})

ruleTester.run('no-public-class-fields', rule, {
valid: [
{code: 'class Foo { bar(){} }'},
{code: 'class Foo { static bar() {} }'},
{code: 'class Foo { bar: AType }'},
{code: 'class Foo { ["bar"]() {} }'},
{code: 'class Foo { static ["bar"]() {} }'},
{code: 'class Foo { static bar: AType }'},
{code: 'class Foo { static bar = () => {} }'},
{code: 'class Foo { static bar = 1 }'},
{code: 'class Foo { bar: AType }'},
{code: 'class Foo { bar = () => {} }'},
{code: 'class Foo { bar = 1 }'},
],
invalid: [
{
code: 'class Foo { ["bar"] = () => {} }',
errors: [
{
message:
'Computed Class Fields are not supported in undefined'
}
]
},
{
code: 'class Foo { ["bar"] = 1 }',
errors: [
{
message:
'Computed Class Fields are not supported in undefined'
}
]
},
{
code: 'class Foo { static ["bar"] = () => {} }',
errors: [
{
message:
'Computed Class Fields are not supported in undefined'
}
]
},
{
code: 'class Foo { static ["bar"] = 1 }',
errors: [
{
message:
'Computed Class Fields are not supported in undefined'
}
]
}
]
})

0 comments on commit d8ce1cb

Please sign in to comment.