Skip to content

useExplicitType

¥Summary

¥How to configure

biome.json
{
"linter": {
"rules": {
"nursery": {
"useExplicitType": "error"
}
}
}
}

¥Description

强制在函数、方法、变量和参数中使用类型。

¥Enforce types in functions, methods, variables, and parameters.

TypeScript 中的函数通常不需要显式地添加返回类型注解。省略返回类型可以减少需要读写的代码量,并允许编译器从函数内容中推断返回类型。

¥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.

但是,显式返回类型确实能让函数返回的类型更加清晰易懂。它们还可以提高包含大量大型函数的大型代码库中 TypeScript 的类型检查性能。显式返回类型通过断言返回类型来降低 bug 的发生概率,并避免因更改一个函数体而导致另一个函数内部出现故障,从而避免 “远程操作” 的意外情况。

¥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.

为模块级变量添加注释可以达到类似的目的。此规则仅允许将字面量和某些对象赋值给未类型化的变量。允许的对象不得包含扩展语法和非字面值。此外,值为 nullundefinedletvar 变量需要显式注解。

¥Annotating module-level variables serves a similar purpose. This rule only allows assignment of literals and some objects to untyped variables. Objects that are allowed must not contain spread syntax and values that aren’t literals. Additionally, let and var variables with null or undefined as value require explicit annotation.

此规则强制函数必须具有显式的返回类型注解。

¥This rule enforces that functions do have an explicit return type annotation.

¥Examples

¥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 returned
var 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 returned
var 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 assertions
var 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.

// Unspecified variable type
function fn(): string {
return "Not inline";
}
const direct = fn();
code-block.ts:5:7 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The variable doesn’t have a type defined.

3 │ return “Not inline”;
4 │ }
> 5 │ const direct = fn();
^^^^^^
6 │

Declaring the type makes the code self-documented and can speed up TypeScript type checking.

Add a type to the variable.

// Unspecified object member type
function fn(): string {
return "Not inline";
}
const nested = { result: fn() };
code-block.ts:5:7 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The variable doesn’t have a type defined.

3 │ return “Not inline”;
4 │ }
> 5 │ const nested = { result: fn() };
^^^^^^
6 │

Declaring the type makes the code self-documented and can speed up TypeScript type checking.

Add a type to the variable.

// let bindings of null and undefined are usually overwritten by other code
let foo = null;
code-block.ts:2:5 lint/nursery/useExplicitType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

The variable doesn’t have a type defined.

1 │ // let bindings of null and undefined are usually overwritten by other code
> 2 │ let foo = null;
^^^
3 │

Declaring the type makes the code self-documented and can speed up TypeScript type checking.

Add a type to the variable.

以下示例对于高阶函数而言是不正确的,因为返回的函数没有指定返回类型:

¥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 body
function 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 body
function 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 body
function 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.

以下示例对于没有返回类型的抽象类 getter 而言是不正确的:

¥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.

以下示例被认为是错误的,因为 arg 的类型是 any

¥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.

¥Valid

// 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';
// A literal value
const PREFIX = "/prefix";
// Explicit variable annotation
function func(): string {
return "";
}
let something: string = func();
class Test {
// No return value should be expected (void)
method(): void {
return;
}
}

以下示例被认为是立即返回扩展名为 as const 的值的函数的正确代码:

¥The following example is considered correct code for a function immediately returning a value with as const:

var func = (value: number) => ({ foo: 'bar', value }) as const;

以下示例对于使用类型断言赋值的情况被认为是正确的代码:

¥The following example is considered correct code for a value assigned using type assertion:

function fn(): string {
return "Not inline";
}
const direct = fn() as string;
const nested = { result: fn() as string };

以下示例被认为是特定表达式上下文(例如立即执行函数表达式 (IIFE)、作为参数传递的函数或数组中的函数)中允许的函数的正确代码:

¥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 types
setTimeout(function() { console.log("Hello!"); }, 1000);
// Callbacks without argument types (immediately nested in a function call)
new Promise((resolve) => resolve(1));
// IIFE
(() => {})();

以下示例被认为是高阶函数的正确代码,其中返回的函数显式指定了返回类型,并且函数体仅包含一条语句:

¥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 type
var arrowFn = () => (): void => {};
// the outer function returns an inner function that has a `void` return type
var 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 annotation
type CallBack = () => void;
var f = (gotcha: CallBack = () => { }): void => { };
// A class property with a type annotation
type MethodType = () => void;
class App {
private method: MethodType = () => { };
}

¥Related links