no-unsafe-return
Disallow returning a value with type
any
from a function.
Extending "plugin:@typescript-eslint/recommended-type-checked"
in an ESLint configuration enables this rule.
This rule requires type information to run.
The any
type in TypeScript is a dangerous "escape hatch" from the type system.
Using any
disables many type checking rules and is generally best used only as a last resort or when prototyping code.
Despite your best intentions, the any
type can sometimes leak into your codebase.
Returning an any
-typed value from a function creates a potential type safety hole and source of bugs in your codebase.
This rule disallows returning any
or any[]
from a function and returning Promise<any>
from an async function.
This rule also compares generic type argument types to ensure you don't return an unsafe any
in a generic position to a function that's expecting a specific type.
For example, it will error if you return Set<any>
from a function declared as returning Set<string>
.
- Flat Config
- Legacy Config
export default tseslint.config({
rules: {
"@typescript-eslint/no-unsafe-return": "error"
}
});
module.exports = {
"rules": {
"@typescript-eslint/no-unsafe-return": "error"
}
};
Try this rule in the playground ↗
Examples
- ❌ Incorrect
- ✅ Correct
function foo1() {
return 1 as any;
}
function foo2() {
return Object.create(null);
}
const foo3 = () => {
return 1 as any;
};
const foo4 = () => Object.create(null);
function foo5() {
return [] as any[];
}
function foo6() {
return [] as Array<any>;
}
function foo7() {
return [] as readonly any[];
}
function foo8() {
return [] as Readonly<any[]>;
}
const foo9 = () => {
return [] as any[];
};
const foo10 = () => [] as any[];
const foo11 = (): string[] => [1, 2, 3] as any[];
async function foo13() {
return Promise.resolve({} as any);
}
// generic position examples
function assignability1(): Set<string> {
return new Set<any>([1]);
}
type TAssign = () => Set<string>;
const assignability2: TAssign = () => new Set<any>([true]);
Open in Playgroundfunction foo1() {
return 1;
}
function foo2() {
return Object.create(null) as Record<string, unknown>;
}
const foo3 = () => [];
const foo4 = () => ['a'];
async function foo5() {
return Promise.resolve(1);
}
function assignability1(): Set<string> {
return new Set<string>(['foo']);
}
type TAssign = () => Set<string>;
const assignability2: TAssign = () => new Set(['foo']);
Open in PlaygroundThere are cases where the rule allows to return any
to unknown
.
Examples of any
to unknown
return that are allowed:
function foo1(): unknown {
return JSON.parse(singleObjString); // Return type for JSON.parse is any.
}
function foo2(): unknown[] {
return [] as any[];
}
Open in PlaygroundOptions
This rule is not configurable.
When Not To Use It
If your codebase has many existing any
s or areas of unsafe code, it may be difficult to enable this rule.
It may be easier to skip the no-unsafe-*
rules pending increasing type safety in unsafe areas of your project.
You might consider using ESLint disable comments for those specific situations instead of completely disabling this rule.
Related To
- Avoiding
any
s with Linting and TypeScript no-explicit-any
no-unsafe-argument
no-unsafe-assignment
no-unsafe-call
no-unsafe-member-access
Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.
See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.