explicit-function-return-type
Require explicit return types on functions and class methods.
Explicit types for function return values makes it clear to any calling code what type is returned. This ensures that the return value is assigned to a variable of the correct type; or in the case where there is no return value, that the calling code doesn't try to use the undefined value when it shouldn't.
Attributes
- Included in configs
- ✅ Recommended
- 🔒 Strict
- Fixable
- 🔧 Automated Fixer
- 💡 Suggestion Fixer
- 💭 Requires type information
Rule Details
This rule aims to ensure that the values returned from functions are of the expected type.
- ❌ Incorrect
- ✅ Correct
// 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;
}
}
module.exports = {
"rules": {
"@typescript-eslint/explicit-function-return-type": "warn"
}
};
Options
This rule accepts an options object with the following properties:
interface Options {
/**
* Whether to allow arrow functions that start with the `void` keyword.
*/
allowConciseArrowFunctionExpressionsStartingWithVoid?: boolean;
/**
* Whether to ignore function expressions (functions which are not part of a declaration).
*/
allowExpressions?: boolean;
/**
* Whether to ignore functions immediately returning another function expression.
*/
allowHigherOrderFunctions?: boolean;
/**
* Whether to ignore type annotations on the variable of function expressions.
*/
allowTypedFunctionExpressions?: boolean;
/**
* Whether to ignore arrow functions immediately returning a `as const` value.
*/
allowDirectConstAssertionInArrowFunctions?: 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,
allowedNames: [],
},
];
Configuring in a mixed JS/TS codebase
If you are working on a codebase within which you lint non-TypeScript code (i.e. .js
/.mjs
/.cjs
/.jsx
), you should ensure that you should use ESLint overrides
to only enable the rule on .ts
/.mts
/.cts
/.tsx
files. If you don't, then you will get unfixable lint errors reported within .js
/.mjs
/.cjs
/.jsx
files.
{
"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
Examples of code for this rule with { allowExpressions: true }
:
- ❌ Incorrect
- ✅ Correct
function test() {}
const fn = () => {};
export default () => {};
node.addEventListener('click', () => {});
node.addEventListener('click', function () {});
const foo = arr.map(i => i * i);
allowTypedFunctionExpressions
Examples of code for this rule with { allowTypedFunctionExpressions: true }
:
- ❌ Incorrect
- ✅ Correct
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 functionWithArg(arg: () => number);
functionWithArg(() => 1);
declare functionWithObjectArg(arg: { method: () => number });
functionWithObjectArg({
method() {
return 1;
},
});
allowHigherOrderFunctions
Examples of code for this rule with { allowHigherOrderFunctions: true }
:
- ❌ Incorrect
- ✅ Correct
var arrowFn = () => () => {};
function fn() {
return function () {};
}
var arrowFn = () => (): void => {};
function fn() {
return function (): void {};
}
allowDirectConstAssertionInArrowFunctions
Examples of code for this rule with { allowDirectConstAssertionInArrowFunctions: true }
:
- ❌ Incorrect
- ✅ Correct
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
Examples of code for this rule with { allowConciseArrowFunctionExpressionsStartingWithVoid: true }
:
- ❌ Incorrect
- ✅ Correct
var join = (a: string, b: string) => `${a}${b}`;
const log = (message: string) => {
console.log(message);
};
var log = (message: string) => void console.log(message);
allowedNames
You may pass function/method names you would like this rule to ignore, like so:
{
"@typescript-eslint/explicit-function-return-type": [
"error",
{
"allowedNames": ["ignoredFunctionName", "ignoredMethodName"]
}
]
}
When Not To Use It
If you don't wish to prevent calling code from using function return values in unexpected ways, then you will not need this rule.
Further Reading
- TypeScript Functions