useExplicitType
Summary
Section titled “Summary”- Rule available since:
v1.9.3
- Diagnostic Category:
lint/nursery/useExplicitType
- This rule doesn’t have a fix.
- The default severity of this rule is error.
- Sources:
- Inspired from
@typescript-eslint/explicit-function-return-type
- Inspired from
@typescript-eslint/explicit-module-boundary-types
- Inspired from
Description
Section titled “Description”Enforce types in functions, methods, variables, and parameters.
Functions in TypeScript often don’t need to be given an explicit return type annotation. Leaving off the return type is less code to read or write and allows the compiler to infer it from the contents of the function.
However, explicit return types do make it visually clearer what type is returned by a function. They can also speed up TypeScript type-checking performance in large codebases with many large functions. Explicit return types also reduce the chance of bugs by asserting the return type, and it avoids surprising “action at a distance,” where changing the body of one function may cause failures inside another function.
This rule enforces that functions do have an explicit return type annotation.
Examples
Section titled “Examples”Invalid
Section titled “Invalid”// Should indicate that no value is returned (void)function test() { return;}
code-block.ts:2:1 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ // Should indicate that no value is returned (void)
> 2 │ function test() {
│ ^^^^^^^^^^^^^
3 │ return;
4 │ }
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
// Should indicate that a number is returnedvar fn = function () { return 1;};
code-block.ts:2:10 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ // Should indicate that a number is returned
> 2 │ var fn = function () {
│ ^^^^^^^^^^^^^
> 3 │ return 1;
> 4 │ };
│ ^
5 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
// Should indicate that a string is returnedvar arrowFn = () => 'test';
code-block.ts:2:15 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ // Should indicate that a string is returned
> 2 │ var arrowFn = () => ‘test’;
│ ^^^^^^^^^^^^
3 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
class Test { // Should indicate that no value is returned (void) method() { return; }}
code-block.ts:3:3 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on member.
1 │ class Test {
2 │ // Should indicate that no value is returned (void)
> 3 │ method() {
│ ^^^^^^^^^^
> 4 │ return;
> 5 │ }
│ ^
6 │ }
7 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the member.
// Should indicate that no value is returned (void)function test(a: number) { a += 1;}
code-block.ts:2:1 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ // Should indicate that no value is returned (void)
> 2 │ function test(a: number) {
│ ^^^^^^^^^^^^^
3 │ a += 1;
4 │ }
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
// Should use const assertionsvar func = (value: number) => ({ type: 'X', value }) as any;
code-block.ts:2:12 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ // Should use const assertions
> 2 │ var func = (value: number) => ({ type: ‘X’, value }) as any;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
The following example is considered incorrect for a higher-order function, as the returned function does not specify a return type:
var arrowFn = () => () => {};
code-block.ts:1:21 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
> 1 │ var arrowFn = () => () => {};
│ ^^^^^^^^
2 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
var arrowFn = () => { return () => { };}
code-block.ts:2:10 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ var arrowFn = () => {
> 2 │ return () => { };
│ ^^^^^^^^^
3 │ }
4 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
The following example is considered incorrect for a higher-order function because the function body contains multiple statements. We only check whether the first statement is a function return.
// A function has multiple statements in the bodyfunction f() { if (x) { return 0; } return (): void => {}}
code-block.ts:2:1 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ // A function has multiple statements in the body
> 2 │ function f() {
│ ^^^^^^^^^^
3 │ if (x) {
4 │ return 0;
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
// A function has multiple statements in the bodyfunction f() { let str = "test"; return (): string => { str; }}
code-block.ts:2:1 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ // A function has multiple statements in the body
> 2 │ function f() {
│ ^^^^^^^^^^
3 │ let str = “test”;
4 │ return (): string => {
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
// A function has multiple statements in the bodyfunction f() { let str = "test";}
code-block.ts:2:1 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function.
1 │ // A function has multiple statements in the body
> 2 │ function f() {
│ ^^^^^^^^^^
3 │ let str = “test”;
4 │ }
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function.
The following example is considered incorrect for an interface method without a return type:
interface Array<Type> { method();}
code-block.ts:2:3 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on member.
1 │ interface Array<Type> {
> 2 │ method();
│ ^^^^^^^^^
3 │ }
4 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the member.
The following example is considered incorrect for a type declaration of a function without a return type:
type MyObject = { (input: string); propertyName: string;};
code-block.ts:2:3 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on member.
1 │ type MyObject = {
> 2 │ (input: string);
│ ^^^^^^^^^^^^^^^^
3 │ propertyName: string;
4 │ };
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the member.
The following example is considered incorrect for an abstract class method without a return type:
abstract class MyClass { public abstract method();}
code-block.ts:2:3 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on member.
1 │ abstract class MyClass {
> 2 │ public abstract method();
│ ^^^^^^^^^^^^^^^^^^^^^^^^^
3 │ }
4 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the member.
The following example is considered incorrect for an abstract class getter without a return type:
abstract class P<T> { abstract get poke();}
code-block.ts:2:3 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on member.
1 │ abstract class P<T> {
> 2 │ abstract get poke();
│ ^^^^^^^^^^^^^^^^^^^^
3 │ }
4 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the member.
The following example is considered incorrect for a function declaration in a namespace without a return type:
declare namespace myLib { function makeGreeting(s: string);}
code-block.ts:2:3 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function declaration.
1 │ declare namespace myLib {
> 2 │ function makeGreeting(s: string);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 │ }
4 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function declaration.
The following example is considered incorrect for a module function export without a return type:
declare module "foo" { export default function bar();}
code-block.ts:2:18 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Missing return type on function declaration.
1 │ declare module “foo” {
> 2 │ export default function bar();
│ ^^^^^^^^^^^^^^^
3 │ }
4 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a return type to the function declaration.
The following example is considered incorrect because resolve
doesn’t have a type annotation.
new Promise((resolve) => resolve(1));
code-block.ts:1:14 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ The parameter doesn’t have a type defined.
> 1 │ new Promise((resolve) => resolve(1));
│ ^^^^^^^
2 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Add a type to the parameter.
The following example is considered incorrect because arg
has any
type.
var arrowFn = (arg: any): string => `test ${arg}`;
code-block.ts:1:21 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ The parameter has an any type.
> 1 │ var arrowFn = (arg: any): string => test ${arg}
;
│ ^^^
2 │
ℹ Declaring the type makes the code self-documented and can speed up TypeScript type checking.
ℹ Replace any with unknown or a more specific type.
// No return value should be expected (void)function test(): void { return;}
// A return value of type numbervar fn = function (): number { return 1;}
// A return value of type stringvar arrowFn = (): string => 'test';
class Test { // No return value should be expected (void) method(): void { return; }}
The following examples are considered correct code for a function immediately returning a value with as const
:
var func = (value: number) => ({ foo: 'bar', value }) as const;
The following examples are considered correct code for a function allowed within specific expression contexts, such as an IIFE, a function passed as an argument, or a function inside an array:
// Callbacks without return typessetTimeout(function() { console.log("Hello!"); }, 1000);
// IIFE(() => {})();
// a function inside an array[function () {}, () => {}];
The following example is considered correct code for a higher-order function, where the returned function explicitly specifies a return type and the function body contains only one statement:
// the outer function returns an inner function that has a `void` return typevar arrowFn = () => (): void => {};
// the outer function returns an inner function that has a `void` return typevar arrowFn = () => { return (): void => { };}
The following examples are considered correct for type annotations on variables in function expressions:
// A function with a type assertion using `as`var asTyped = (() => '') as () => string;
// A function with a type assertion using `<>`var castTyped = <() => string>(() => '');
// A variable declarator with a type annotation.type FuncType = () => string;var arrowFn: FuncType = () => 'test';
// A function is a default parameter with a type annotationtype CallBack = () => void;var f = (gotcha: CallBack = () => { }): void => { };
// A class property with a type annotationtype MethodType = () => void;class App { private method: MethodType = () => { };}
How to configure
Section titled “How to configure”{ "linter": { "rules": { "nursery": { "useExplicitType": "error" } } }}