> For AI agents: the complete documentation index is available at https://rslint.rs/llms.txt, the full documentation bundle is available at https://rslint.rs/llms-full.txt.

# func-name-matching

[Added in v0.8.2](https://github.com/web-infra-dev/rslint/releases/tag/v0.8.2)
## Configuration


```ts title=rslint.config.ts
import { defineConfig, js } from '@rslint/core';

export default defineConfig([
  js.configs.recommended,
  {
    rules: {
      'func-name-matching': 'error',
    },
  },
]);
```

## Rule Details

This rule requires function names to match the name of the variable or property to which they are assigned. The rule will ignore property assignments where the property name is a literal that is not a valid identifier in the ECMAScript version specified in your configuration (which defaults to the latest version).

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

```javascript
let foo = function bar() {};
foo = function bar() {};
const obj = { foo: function bar() {} };
obj.foo = function bar() {};
obj["foo"] = function bar() {};
({ ["foo"]: function bar() {} });

class C {
  foo = function bar() {};
}
```

Examples of **incorrect** code for this rule with `"never"`:

```json
{ "func-name-matching": ["error", "never"] }
```

```javascript
let foo = function foo() {};
foo = function foo() {};
const obj = { foo: function foo() {} };
obj.foo = function foo() {};
obj["foo"] = function foo() {};
({ ["foo"]: function foo() {} });

class C {
  foo = function foo() {};
}
```

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

```javascript
const foo = function foo() {};
const foo1 = function () {};
const foo2 = () => {};
foo = function foo() {};

const obj = { foo: function foo() {} };
obj.foo = function foo() {};
obj["foo"] = function foo() {};
obj["foo//bar"] = function foo() {};
obj[foo] = function bar() {};

const obj1 = { [foo]: function bar() {} };
const obj2 = { "foo//bar": function foo() {} };
const obj3 = { foo: function () {} };

obj["x" + 2] = function bar() {};
const [bar] = [function bar() {}];
({ [foo]: function bar() {} });

class C {
  foo = function foo() {};
  baz = function () {};
}

// private names are ignored
class D {
  #foo = function foo() {};
  #bar = function foo() {};
  baz() {
    this.#foo = function foo() {};
    this.#foo = function bar() {};
  }
}

module.exports = function foo(name) {};
module["exports"] = function foo(name) {};
```

Examples of **correct** code for this rule with `"never"`:

```json
{ "func-name-matching": ["error", "never"] }
```

```javascript
let foo = function bar() {};
const foo1 = function () {};
const foo2 = () => {};
foo = function bar() {};

const obj = { foo: function bar() {} };
obj.foo = function bar() {};
obj["foo"] = function bar() {};
obj["foo//bar"] = function foo() {};
obj[foo] = function foo() {};

const obj1 = { foo: function bar() {} };
const obj2 = { [foo]: function foo() {} };
const obj3 = { "foo//bar": function foo() {} };
const obj4 = { foo: function () {} };

obj["x" + 2] = function bar() {};
const [bar] = [function bar() {}];
({ [foo]: function bar() {} });

class C {
  foo = function bar() {};
  baz = function () {};
}

// private names are ignored
class D {
  #foo = function foo() {};
  #bar = function foo() {};
  baz() {
    this.#foo = function foo() {};
    this.#foo = function bar() {};
  }
}

module.exports = function foo(name) {};
module["exports"] = function foo(name) {};
```

## Options

This rule takes an optional string of `"always"` or `"never"` (when omitted, it defaults to `"always"`), and an optional options object with two properties `considerPropertyDescriptor` and `includeCommonJSModuleExports`.

### considerPropertyDescriptor

A boolean value that defaults to `false`. If `considerPropertyDescriptor` is set to true, the check will take into account the use of `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty`.

Examples of **correct** code for the `{ "considerPropertyDescriptor": true }` option:

```json
{ "func-name-matching": ["error", { "considerPropertyDescriptor": true }] }
```

```javascript
const obj = {};
Object.create(obj, { foo: { value: function foo() {} } });
Object.defineProperty(obj, "bar", { value: function bar() {} });
Object.defineProperties(obj, { baz: { value: function baz() {} } });
Reflect.defineProperty(obj, "foo", { value: function foo() {} });
```

Examples of **incorrect** code for the `{ "considerPropertyDescriptor": true }` option:

```json
{ "func-name-matching": ["error", { "considerPropertyDescriptor": true }] }
```

```javascript
const obj = {};
Object.create(obj, { foo: { value: function bar() {} } });
Object.defineProperty(obj, "bar", { value: function baz() {} });
Object.defineProperties(obj, { baz: { value: function foo() {} } });
Reflect.defineProperty(obj, "foo", { value: function value() {} });
```

### includeCommonJSModuleExports

A boolean value that defaults to `false`. If `includeCommonJSModuleExports` is set to true, `module.exports` and `module["exports"]` will be checked by this rule.

Examples of **incorrect** code for the `{ "includeCommonJSModuleExports": true }` option:

```json
{ "func-name-matching": ["error", { "includeCommonJSModuleExports": true }] }
```

```javascript
module.exports = function foo(name) {};
module["exports"] = function foo(name) {};
```

## Differences from ESLint

- For a property whose name comes from a string literal, rslint decides whether that name is a valid identifier using ts-go's current Unicode character table. ESLint's `esutils@2.0.3` uses frozen tables for both its ES5 and ES6 checks. This can make rslint check a property that ESLint leaves unchecked: for example, `{ "ᢅ": function foo() {} }` under `ecmaVersion: 5`, or `{ "𐕰": function foo() {} }` under a modern version. Assignment expressions have the same character-table difference at every configured version because ESLint always uses its default ES5 check on that path, while rslint uses ts-go's current table.

- With `considerPropertyDescriptor` enabled, an `Object.defineProperties()` or `Object.create()` descriptor map is checked against its entry's key when that key is an identifier (e.g. `{ bar: { value: function bar() {} } }`). ESLint also reports entries keyed by a string or numeric literal (e.g. `{ "bar": { value: function baz() {} } }`), but names the property `undefined` in the message; rslint leaves those entries unchecked.

## Original Documentation

- [ESLint: func-name-matching](https://eslint.org/docs/latest/rules/func-name-matching)
- [Source code](https://github.com/eslint/eslint/blob/v10.8.1/lib/rules/func-name-matching.js)
