AbsoluteJS

absolute/no-explicit-return-type

Disallow explicit return type annotations on functions, except for type-predicate guards and inline object-literal returns.

TypeScriptSuggestion
View on GitHub

#Rule Details

Removes explicit return-type annotations where TypeScript already infers the type accurately. Inference stays correct as the implementation changes, so a hand-written return type is redundant maintenance that can silently drift from the real return value.

Four cases are intentionally allowed: type-predicate guards (x is T), arrows that directly return an object literal ((): T => ({ ... })), block-bodied functions whose single statement returns an object literal (the style-object pattern), and recursive/self-referential functions, where TypeScript actually requires the annotation.

#Examples

Incorrect
TS
function getName(): string {
	return 'Ada';
}

const toUpper = (value: string): string => value.toUpperCase();

const load = function (): number { return 1; };
Correct
TS
function getName() {
	return 'Ada'; // inferred as string
}

const toUpper = (value: string) => value.toUpperCase();

Type predicates are allowed

TS
// Type guards keep their predicate annotation
function isString(value: unknown): value is string {
	return typeof value === 'string';
}
TS
// Inline object returns (e.g. style objects) are allowed
const getStyle = (): CSSProperties => ({ color: 'red' });

// Recursive functions require the annotation, so it is allowed
function depth(node: TreeNode): number {
	return node.children.reduce((sum, child) => sum + depth(child), 0);
}

#Configuration

Enable this rule in your ESLint configuration:

JS
{
	rules: {
		'absolute/no-explicit-return-type': 'error'
	}
}

#When Not To Use It

On a public library surface you may want explicit return types so the published .d.ts is stable and reviewable, and so refactors that change an inferred type fail loudly. In that case prefer requiring return types instead of forbidding them.

#Resources