close

func-style

Unreleased

Configuration

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

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

Rule Details

There are two ways of defining functions in JavaScript: function declarations and function expressions assigned to variables. Function expressions can either be arrow functions or use the function keyword with an optional name.

// function declaration
function doSomething() {
  // ...
}

// arrow function expression assigned to a variable
const doSomethingElse = () => {
  // ...
};

// function expression assigned to a variable
const doSomethingAgain = function () {
  // ...
};

The primary difference between function declarations and function expressions is that declarations are hoisted to the top of the scope in which they are defined, which allows using the function before its declaration; a function expression must be defined before it is used.

This rule enforces a particular type of function style, either function declarations or expressions assigned to variables.

This rule does not apply to all functions. A callback function passed as an argument to another function, or a method assigned to an object, is not checked by this rule.

Examples of incorrect code for this rule with the default "expression" option:

function foo() {
  // ...
}

Examples of correct code for this rule with the default "expression" option:

const foo = function () {
  // ...
};

const foo1 = () => {};

Overloaded function declarations (multiple declarations of the same name with different parameter or return types) are never reported by this rule, regardless of the configured style:

function process(value: string): string;
function process(value: number): number;
function process(value: unknown) {
  return value;
}

Examples of incorrect code for this rule with the "declaration" option:

{ "func-style": ["error", "declaration"] }
const foo = function () {
  // ...
};

const foo1 = () => {};

Examples of correct code for this rule with the "declaration" option:

{ "func-style": ["error", "declaration"] }
function foo() {
  // ...
}

// Methods (functions assigned to objects) are not checked by this rule
SomeObject.foo = function () {
  // ...
};

Options

This rule has a string option:

  • "expression" (default) requires the use of function expressions instead of function declarations
  • "declaration" requires the use of function declarations instead of function expressions

This rule has an object option:

  • "allowArrowFunctions": true (default false) allows the use of arrow functions when the string option is "declaration". Arrow functions are always allowed when the string option is "expression", regardless of this option.
  • "allowTypeAnnotation": true (default false) allows a function expression or arrow function whose variable declaration has a type annotation, regardless of allowArrowFunctions. This option applies only when the string option is "declaration".
  • "overrides":
    • "namedExports": "expression" | "declaration" | "ignore" overrides the function style required for named exports. "ignore" accepts either style.

allowArrowFunctions

Examples of additional correct code for this rule with { "allowArrowFunctions": true }:

{ "func-style": ["error", "declaration", { "allowArrowFunctions": true }] }
const foo = () => {};

allowTypeAnnotation

Examples of incorrect code for this rule with { "allowTypeAnnotation": true }:

{ "func-style": ["error", "declaration", { "allowTypeAnnotation": true }] }
const foo = function (): void {};

Examples of correct code for this rule with { "allowTypeAnnotation": true }:

{ "func-style": ["error", "declaration", { "allowTypeAnnotation": true }] }
type Fn = () => undefined;

const foo: Fn = function () {};

const bar: Fn = () => {};

overrides.namedExports

Examples of incorrect code for this rule with { "overrides": { "namedExports": "expression" } }:

{
  "func-style": [
    "error",
    "declaration",
    { "overrides": { "namedExports": "expression" } }
  ]
}
export function foo() {
  // ...
}

Examples of correct code for this rule with { "overrides": { "namedExports": "expression" } }:

{
  "func-style": [
    "error",
    "declaration",
    { "overrides": { "namedExports": "expression" } }
  ]
}
export const foo = function () {
  // ...
};

export const bar = () => {};

Examples of incorrect code for this rule with { "overrides": { "namedExports": "declaration" } }:

{
  "func-style": [
    "error",
    "expression",
    { "overrides": { "namedExports": "declaration" } }
  ]
}
export const foo = function () {
  // ...
};

export const bar = () => {};

Examples of correct code for this rule with { "overrides": { "namedExports": "declaration" } }:

{
  "func-style": [
    "error",
    "expression",
    { "overrides": { "namedExports": "declaration" } }
  ]
}
export function foo() {
  // ...
}

Examples of correct code for this rule with { "overrides": { "namedExports": "ignore" } }:

{
  "func-style": [
    "error",
    "expression",
    { "overrides": { "namedExports": "ignore" } }
  ]
}
export const foo = function () {
  // ...
};

export const bar = () => {};

export function baz() {
  // ...
}

Original Documentation