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;
}
}
Playgroundで開く// 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;
}
}
Playgroundで開くオプション
このルールは次のオプションを受け入れます。
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 () => {};
Playgroundで開くnode.addEventListener('click', () => {});
node.addEventListener('click', function () {});
const foo = arr.map(i => i * i);
Playgroundで開くallowTypedFunctionExpressions
{ allowTypedFunctionExpressions: true }
を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
let arrowFn = () => 'test';
let funcExpr = function () {
return 'test';
};
let objectProp = {
foo: () => 1,
};
Playgroundで開く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;
},
});
Playgroundで開くallowHigherOrderFunctions
{ allowHigherOrderFunctions: true }
を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
var arrowFn = () => () => {};
function fn() {
return function () {};
}
Playgroundで開くvar arrowFn = () => (): void => {};
function fn() {
return function (): void {};
}
Playgroundで開くallowDirectConstAssertionInArrowFunctions
{ allowDirectConstAssertionInArrowFunctions: true }
を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
const func = (value: number) => ({ type: 'X', value }) as any;
const func = (value: number) => ({ type: 'X', value }) as Action;
Playgroundで開くconst func = (value: number) => ({ foo: 'bar', value }) as const;
const func = () => x as const;
Playgroundで開くallowConciseArrowFunctionExpressionsStartingWithVoid
{ allowConciseArrowFunctionExpressionsStartingWithVoid: true }
を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
var join = (a: string, b: string) => `${a}${b}`;
const log = (message: string) => {
console.log(message);
};
Playgroundで開くvar log = (message: string) => void console.log(message);
Playgroundで開くallowFunctionsWithoutTypeParameters
{ allowFunctionsWithoutTypeParameters: true }
を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
function foo<T>(t: T) {
return t;
}
const bar = <T>(t: T) => t;
Playgroundで開く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;
Playgroundで開くallowedNames
このルールで無視したい関数/メソッド名を次のように渡すことができます。
{
"@typescript-eslint/explicit-function-return-type": [
"error",
{
"allowedNames": ["ignoredFunctionName", "ignoredMethodName"]
}
]
}
allowIIFEs
{ allowIIFEs: true }
を使用したこのルールのコード例
- ❌ 正しくない
- ✅ 正しい
var func = () => 'foo';
Playgroundで開くvar foo = (() => 'foo')();
var bar = (function () {
return 'bar';
})();
Playgroundで開く使用しない場合
関数の戻り値の型を明示的に記述する追加コストが視覚的な明確さに見合う価値がないと判断した場合、またはプロジェクトが型チェックのパフォーマンスに影響を与えるほど大きくない場合は、このルールは必要ありません。
参考資料
- TypeScript 関数