Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 deletions docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
| [vue/one-component-per-file](./one-component-per-file.md) | enforce that each component should be in its own file | |
| [vue/prop-name-casing](./prop-name-casing.md) | enforce specific casing for the Prop name in Vue components | |
| [vue/require-default-prop](./require-default-prop.md) | require default value for props | |
| [vue/require-emit-types](./require-emit-types.md) | require type definitions in emits | |
| [vue/require-explicit-emits](./require-explicit-emits.md) | require `emits` option with name triggered by `$emit()` | |
| [vue/require-prop-types](./require-prop-types.md) | require type definitions in props | |
| [vue/singleline-html-element-content-newline](./singleline-html-element-content-newline.md) | require a line break before and after the contents of a singleline element | :wrench: |
Expand Down
61 changes: 61 additions & 0 deletions docs/rules/require-emit-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/require-emit-types
description: require type definitions in emits
---
# vue/require-emit-types

> require type definitions in emits

- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>
- :gear: This rule is included in `"plugin:vue/vue3-strongly-recommended"` and `"plugin:vue/vue3-recommended"`.

## :book: Rule Details

This rule enforces that a `emits` statement contains type definition.

Declaring `emits` with types can bring better maintenance.
Even if using with TypeScript, this can provide better type inference when annotating parameters with types.

<eslint-code-block :rules="{'vue/require-emit-types': ['error']}">

```vue
<script>
/* ✓ GOOD */
Vue.component('foo', {
emits: {
// Emit with arguments
foo: (payload) => { /* validate payload */ },
// Emit without parameters
bar: () => true,
}
})

/* ✗ BAD */
Vue.component('bar', {
emits: ['foo']
})

Vue.component('baz', {
emits: {
foo: null,
}
})
</script>
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :books: Further Reading

- [API Reference](https://v3.vuejs.org/api/options-data.html#emits)

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/require-emit-types.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/require-emit-types.js)
1 change: 1 addition & 0 deletions lib/configs/vue3-strongly-recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
'vue/one-component-per-file': 'warn',
'vue/prop-name-casing': 'warn',
'vue/require-default-prop': 'warn',
'vue/require-emit-types': 'warn',
'vue/require-explicit-emits': 'warn',
'vue/require-prop-types': 'warn',
'vue/singleline-html-element-content-newline': 'warn',
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ module.exports = {
'require-component-is': require('./rules/require-component-is'),
'require-default-prop': require('./rules/require-default-prop'),
'require-direct-export': require('./rules/require-direct-export'),
'require-emit-types': require('./rules/require-emit-types'),
'require-explicit-emits': require('./rules/require-explicit-emits'),
'require-name-property': require('./rules/require-name-property'),
'require-prop-type-constructor': require('./rules/require-prop-type-constructor'),
Expand Down
69 changes: 69 additions & 0 deletions lib/rules/require-emit-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* @fileoverview Emit definitions should be detailed
* @author Pig Fang
*/
'use strict'

const utils = require('../utils')

/**
* @typedef {import('../utils').ComponentArrayEmit} ComponentArrayEmit
* @typedef {import('../utils').ComponentObjectEmit} ComponentObjectEmit
*/

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

module.exports = {
meta: {
type: 'suggestion',
docs: {
description: 'require type definitions in emits',
categories: ['vue3-strongly-recommended'],
url: 'https://eslint.vuejs.org/rules/require-emit-types.html'
},
fixable: null,
messages: {
missing: 'Emit "{{name}}" should define at least its type.'
},
schema: []
},
/** @param {RuleContext} context */
create(context) {
// ----------------------------------------------------------------------
// Helpers
// ----------------------------------------------------------------------

/**
* @param {ComponentArrayEmit|ComponentObjectEmit} emit
*/
function checker({ value, node, emitName }) {
const hasType =
!!value &&
(value.type === 'ArrowFunctionExpression' ||
value.type === 'FunctionExpression')

if (!hasType) {
const name =
emitName ||
(node.type === 'Identifier' && node.name) ||
'Unknown emit'

context.report({
node,
messageId: 'missing',
data: { name }
})
}
}

// ----------------------------------------------------------------------
// Public
// ----------------------------------------------------------------------

return utils.executeOnVue(context, (obj) => {
utils.getComponentEmits(obj).forEach(checker)
})
}
}
Loading