Skip to content

useUnifiedTypeSignatures

biome.json
{
"linter": {
"rules": {
"style": {
"useUnifiedTypeSignatures": "error"
}
}
}
}

Disallow overload signatures that can be unified into a single signature.

Overload signatures that can be merged into a single signature are redundant and should be avoided. This rule helps simplify function signatures by combining overloads by making parameters optional and/or using type unions.

function f(a: number): void;
function f(a: string): void;
code-block.ts:1:1 lint/style/useUnifiedTypeSignatures  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Multiple similar overload signatures are hard to read and maintain.

> 1 │ function f(a: number): void;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │ function f(a: string): void;
3 │

Unsafe fix: Combine overloads using a type union.

1 - function·f(a:·number):·void;
2 - function·f(a:·string):·void;
1+
2+ function·f(a:·string·|·number):·void;
3 3

function f({ a }: Record<"a", string>): void;
function f({ a }: Record<"a", boolean>): void;
function f(obj: any): void {};
code-block.ts:1:1 lint/style/useUnifiedTypeSignatures  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Multiple similar overload signatures are hard to read and maintain.

> 1 │ function f({ a }: Record<“a”, string>): void;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │ function f({ a }: Record<“a”, boolean>): void;
3 │ function f(obj: any): void {};

Unsafe fix: Combine overloads using a type union.

1 - function·f({·a·}:·Record<a,·string>):·void;
2 - function·f({·a·}:·Record<a,·boolean>):·void;
1+
2+ function·f({·a·}:·Record<a,·boolean>·|·Record<a,·string>):·void;
3 3 function f(obj: any): void {};
4 4

type T = {
a(): void;
a(x: number): void;
}
code-block.ts:2:5 lint/style/useUnifiedTypeSignatures  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Multiple similar overload signatures are hard to read and maintain.

1 │ type T = {
> 2 │ a(): void;
^^^^^^^^^^
3 │ a(x: number): void;
4 │ }

Unsafe fix: Combine overloads by making parameters optional.

1 1 type T = {
2 - ····a():·void;
3 - ····a(x:·number):·void;
2+ ····a(x?:·number):·void;
4 3 }
5 4

interface I {
(): void;
(x: number): void;
}
code-block.ts:2:5 lint/style/useUnifiedTypeSignatures  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Multiple similar overload signatures are hard to read and maintain.

1 │ interface I {
> 2 │ (): void;
^^^^^^^^^
3 │ (x: number): void;
4 │ }

Unsafe fix: Combine overloads by making parameters optional.

1 1 interface I {
2 - ····():·void;
3 - ····(x:·number):·void;
2+ ····(x?:·number):·void;
4 3 }
5 4

export function fizzbuzz([fizz, buzz]: [number, number]): void;
export function fizzbuzz([fizz, buzz]: [string, string]): void;
export default function fizzbuzz([fizz, buzz]: [string | number, string | number]): void {}
code-block.ts:1:1 lint/style/useUnifiedTypeSignatures  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Multiple similar overload signatures are hard to read and maintain.

> 1 │ export function fizzbuzz([fizz, buzz]: [number, number]): void;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │ export function fizzbuzz([fizz, buzz]: [string, string]): void;
3 │ export default function fizzbuzz([fizz, buzz]: [string | number, string | number]): void {}

Unsafe fix: Combine overloads using a type union.

1 - export·function·fizzbuzz([fizz,·buzz]:·[number,·number]):·void;
2 - export·function·fizzbuzz([fizz,·buzz]:·[string,·string]):·void;
1+
2+ export·function·fizzbuzz([fizz,·buzz]:·[string,·string]·|·[number,·number]):·void;
3 3 export default function fizzbuzz([fizz, buzz]: [string | number, string | number]): void {}
4 4

function f(a: number | string): void {}
function f({ a }: Record<"a", string | boolean>): void;
interface I {
a(x?: number): void;
}
export function fizzbuzz([fizz, buzz]: [number, number] | [string, string]): void;
export default function fizzbuzz([fizz, buzz]: [string | number, string | number]): void {}

Different return types cannot be merged:

interface I {
f(): void;
f(x: number): number;
}

Different type parameters cannot be merged:

function f<T extends number>(x: T): void;
function f<T extends string>(x: T): void;
function f(x: unknown): void {}

Different rest signatures cannot be merged: (cf https://github.com/microsoft/TypeScript/issues/5077)

function foo(...x: string[]): void;
function foo(...x: number[]): void;
function foo(...x: any[]): void {}

If set to true, overloads with differently named parameters will be ignored, even if said parameters would be of otherwise mergeable types.

Parameter declarations that lack specified “names” (such as array spread and destructuring literals) will be ignored for this check.

Default: false

biome.json
{
"linter": {
"rules": {
"style": {
"useUnifiedTypeSignatures": {
"options": {
"ignoreDifferentlyNamedParameters": true
}
}
}
}
}
}
function bake(numApples: number): void;
function bake(cakeType: string): void;

If set to true, overloads with different JSDoc comments from one another will be ignored. Ones with identical comments will be merged as normal.

Default: false

biome.json
{
"linter": {
"rules": {
"style": {
"useUnifiedTypeSignatures": {
"options": {
"ignoreDifferentJsDoc": true
}
}
}
}
}
}
/** Print foo + 1 */
function doThing(foo: number): void;
/** Print foo concatenated with 3 */
function doThing(foo: string): void;
/** @deprecated - don't use this, it crashes the program */
function doThing(foo: boolean): void;