explicit-function-return-type
関数とクラスメソッドに明示的な戻り値の型を要求します。
TypeScriptの関数では、多くの場合、明示的な戻り値の型注釈を与える必要はありません。戻り値の型を省略すると、読み書きするコードが少なくなり、コンパイラが関数の内容から型を推論できるようになります。
しかし、明示的な戻り値の型は、関数が返す型を視覚的に明確にします。また、多くの大きな関数を持つ大規模なコードベースでは、TypeScriptの型チェックのパフォーマンスを向上させることもできます。
このルールは、関数に明示的な戻り値の型注釈があることを強制します。
module.exports = {
  "rules": {
    "@typescript-eslint/explicit-function-return-type": "error"
  }
};
このルールをPlaygroundでお試しください ↗
例
- ❌ 正しくない
- ✅ 正しい
// Should indicate that no value is returned (void)
function test() {
  return;
}
// Should indicate that a number is returned
var fn = function () {
  return 1;
};
// Should indicate that a string is returned
var arrowFn = () => 'test';
class Test {
  // Should indicate that no value is returned (void)
  method() {
    return;
  }
}
// No return value should be expected (void)
function test(): void {
  return;
}
// A return value of type number
var fn = function (): number {
  return 1;
};
// A return value of type string
var arrowFn = (): string => 'test';
class Test {
  // No return value should be expected (void)
  method(): void {
    return;
  }
}
オプション
このルールは次のオプションを受け入れます。
type Options = [
  {
    /** Whether to allow arrow functions that start with the `void` keyword. */
    allowConciseArrowFunctionExpressionsStartingWithVoid?: boolean;
    /** Whether to ignore arrow functions immediately returning a `as const` value. */
    allowDirectConstAssertionInArrowFunctions?: boolean;
    /** Whether to ignore function expressions (functions which are not part of a declaration). */
    allowExpressions?: boolean;
    /** Whether to ignore functions that don't have generic type parameters. */
    allowFunctionsWithoutTypeParameters?: boolean;
    /** Whether to ignore functions immediately returning another function expression. */
    allowHigherOrderFunctions?: boolean;
    /** Whether to ignore immediately invoked function expressions (IIFEs). */
    allowIIFEs?: boolean;
    /** Whether to ignore type annotations on the variable of function expressions. */
    allowTypedFunctionExpressions?: boolean;
    /** An array of function/method names that will not have their arguments or return values checked. */
    allowedNames?: string[];
  },
];
const defaultOptions: Options = [
  {
    allowExpressions: false,
    allowTypedFunctionExpressions: true,
    allowHigherOrderFunctions: true,
    allowDirectConstAssertionInArrowFunctions: true,
    allowConciseArrowFunctionExpressionsStartingWithVoid: false,
    allowFunctionsWithoutTypeParameters: false,
    allowedNames: [],
    allowIIFEs: false,
  },
];
混合JS/TSコードベースでの設定
TypeScript以外のコード(つまり、.js/.mjs/.cjs/.jsx)をlintするコードベースで作業している場合は、ESLintのoverridesを使用して、.ts/.mts/.cts/.tsxファイルでのみルールを有効にする必要があります。 そうしないと、.js/.mjs/.cjs/.jsxファイル内で修正できないlintエラーが報告されます。
{
  "rules": {
    // disable the rule for all files
    "@typescript-eslint/explicit-function-return-type": "off",
  },
  "overrides": [
    {
      // enable the rule specifically for TypeScript files
      "files": ["*.ts", "*.mts", "*.cts", "*.tsx"],
      "rules": {
        "@typescript-eslint/explicit-function-return-type": "error",
      },
    },
  ],
}
allowExpressions
{ allowExpressions: true }を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
function test() {}
const fn = () => {};
export default () => {};
node.addEventListener('click', () => {});
node.addEventListener('click', function () {});
const foo = arr.map(i => i * i);
allowTypedFunctionExpressions
{ allowTypedFunctionExpressions: true }を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
let arrowFn = () => 'test';
let funcExpr = function () {
  return 'test';
};
let objectProp = {
  foo: () => 1,
};
type FuncType = () => string;
let arrowFn: FuncType = () => 'test';
let funcExpr: FuncType = function () {
  return 'test';
};
let asTyped = (() => '') as () => string;
let castTyped = <() => string>(() => '');
interface ObjectType {
  foo(): number;
}
let objectProp: ObjectType = {
  foo: () => 1,
};
let objectPropAs = {
  foo: () => 1,
} as ObjectType;
let objectPropCast = <ObjectType>{
  foo: () => 1,
};
declare function functionWithArg(arg: () => number);
functionWithArg(() => 1);
declare function functionWithObjectArg(arg: { method: () => number });
functionWithObjectArg({
  method() {
    return 1;
  },
});
allowHigherOrderFunctions
{ allowHigherOrderFunctions: true }を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
var arrowFn = () => () => {};
function fn() {
  return function () {};
}
var arrowFn = () => (): void => {};
function fn() {
  return function (): void {};
}
allowDirectConstAssertionInArrowFunctions
{ allowDirectConstAssertionInArrowFunctions: true }を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
const func = (value: number) => ({ type: 'X', value }) as any;
const func = (value: number) => ({ type: 'X', value }) as Action;
const func = (value: number) => ({ foo: 'bar', value }) as const;
const func = () => x as const;
allowConciseArrowFunctionExpressionsStartingWithVoid
{ allowConciseArrowFunctionExpressionsStartingWithVoid: true }を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
var join = (a: string, b: string) => `${a}${b}`;
const log = (message: string) => {
  console.log(message);
};
var log = (message: string) => void console.log(message);
allowFunctionsWithoutTypeParameters
{ allowFunctionsWithoutTypeParameters: true }を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
function foo<T>(t: T) {
  return t;
}
const bar = <T>(t: T) => t;
function foo<T>(t: T): T {
  return t;
}
const bar = <T>(t: T): T => t;
function allowedFunction(x: string) {
  return x;
}
const allowedArrow = (x: string) => x;
allowedNames
このルールで無視したい関数/メソッド名を次のように渡すことができます。
{
  "@typescript-eslint/explicit-function-return-type": [
    "error",
    {
      "allowedNames": ["ignoredFunctionName", "ignoredMethodName"]
    }
  ]
}
allowIIFEs
{ allowIIFEs: true }を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
var func = () => 'foo';
var foo = (() => 'foo')();
var bar = (function () {
  return 'bar';
})();
使用しない場合
関数の戻り値の型を明示的に記述する追加コストが視覚的な明確さに見合う価値がないと判断した場合、またはプロジェクトが型チェックのパフォーマンスに影響を与えるほど大きくない場合は、このルールは必要ありません。
参考資料
- TypeScript 関数