noBannedTypes
Summary
Section titled “Summary”- Rule available since:
v1.0.0 - Diagnostic Category:
lint/complexity/noBannedTypes - This rule is recommended, which means is enabled by default.
- This rule has a safe fix.
- The default severity of this rule is warning.
- Sources:
- Same as
@typescript-eslint/ban-types
- Same as
How to configure
Section titled “How to configure”{ "linter": { "rules": { "complexity": { "noBannedTypes": "error" } } }}Description
Section titled “Description”Disallow primitive type aliases and misleading types.
This rule aims to prevent usage of potentially “misleading” types and type aliases which may behave unexpectedly.
Disallow “boxed object” types like Boolean and Number
Section titled “Disallow “boxed object” types like Boolean and Number”JavaScript’s 8 data types are described in TypeScript by the lowercase types
undefined, null, boolean, number, string, bigint, symbol, and object.
The latter 6 also have uppercase variants, which instead represent interfaces with the shared properties of their primitive counterparts.
Due to the nature of structural typing, these uppercase types accept both primitive values and non-primitive “boxed object”s
like new Boolean(true), despite the two behaving differently in many circumstances like equality and truthiness.
It is thus considered best practice to avoid these “boxed types” in favor of their lowercase primitive counterparts.
Disallow the unsafe Function type
Section titled “Disallow the unsafe Function type”TypeScript’s built-in Function type is capable of accepting callbacks of any shape or form,
behaving equivalent to (...rest: any[]) => any (which uses the unsafe any type) when called directly.
It also accepts classes or plain objects that happen to possess all properties of the Function class,
which is likewise a potential source of confusion.
As such, it is almost always preferable to explicitly specify function parameters and return types where possible.
When a generic “catch-all” callback type is required, one of the following can be used instead:
() => void: A function that accepts no parameters and whose return value is ignored(...args: never) => unknown: A “top type” for functions that can be assigned any function type, but can’t be called directly
Disallow the misleading empty object type {}
Section titled “Disallow the misleading empty object type {}”In TypeScript, the type {} doesn’t represent an empty object (as many new to the language may assume).
It actually accepts any non-nullish value, including non-object primitives.
The following TypeScript example is thus perfectly valid:
const n: {} = 0;code-block.ts:1:10 lint/complexity/noBannedTypes ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Don’t use ’{}’ as a type.
> 1 │ const n: {} = 0;
│ ^^
2 │
ℹ ’{}’ accepts any non-nullable value, including non-object primitives like ‘123’ and ‘true’.
- If you want a type meaning “any arbitrary object”, use ‘object’ instead.
- If you want a type meaning “any value”, use ‘unknown’ instead.
- If you want a type meaning “an object without any properties”, use ’{ [k: string]: never }’ or ‘Record<string, never>’ instead.
ℹ If that’s really what you want, use an inline disable comment.
Often, developers writing {} actually mean one of the following:
object: Represents any object valueunknown: Represents any value at all, includingnullandundefined{ [k: string]: never }orRecord<string, never>: Represent object types that disallow property access
To avoid confusion, this rule forbids the use of the type {}, except in two situations:
- In type constraints to restrict a generic type to non-nullable types:
function f<T extends {}>(x: T) { assert(x != null);}- In a type intersection to narrow a type to its non-nullable equivalent type:
type NonNullableMyType = MyType & {};In this last case, you can also use the NonNullable utility type to the same effect:
type NonNullableMyType = NonNullable<MyType>;Examples
Section titled “Examples”Invalid
Section titled “Invalid”let foo: String = "bar";code-block.ts:1:10 lint/complexity/noBannedTypes FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Don’t use ‘String’ as a type.
> 1 │ let foo: String = “bar”;
│ ^^^^^^
2 │
ℹ Prefer using lowercase primitive types instead of uppercase “boxed object” types.
‘String’ accepts anything that implements the corresponding interface - both primitives and “primitive-like” objects.
It is considered best practice to use ‘string’ instead in nearly all circumstances.
ℹ If that’s really what you want, use an inline disable comment.
ℹ Safe fix: Use ‘string’ instead.
1 │ - let·foo:·String·=·“bar”;
1 │ + let·foo:·string·=·“bar”;
2 2 │
const bool = true as Boolean;code-block.ts:1:22 lint/complexity/noBannedTypes FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Don’t use ‘Boolean’ as a type.
> 1 │ const bool = true as Boolean;
│ ^^^^^^^
2 │
ℹ Prefer using lowercase primitive types instead of uppercase “boxed object” types.
‘Boolean’ accepts anything that implements the corresponding interface - both primitives and “primitive-like” objects.
It is considered best practice to use ‘boolean’ instead in nearly all circumstances.
ℹ If that’s really what you want, use an inline disable comment.
ℹ Safe fix: Use ‘boolean’ instead.
1 │ - const·bool·=·true·as·Boolean;
1 │ + const·bool·=·true·as·boolean;
2 2 │
let invalidTuple: [string, Number] = ["foo", 12];code-block.ts:1:28 lint/complexity/noBannedTypes FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Don’t use ‘Number’ as a type.
> 1 │ let invalidTuple: [string, Number] = [“foo”, 12];
│ ^^^^^^
2 │
ℹ Prefer using lowercase primitive types instead of uppercase “boxed object” types.
‘Number’ accepts anything that implements the corresponding interface - both primitives and “primitive-like” objects.
It is considered best practice to use ‘number’ instead in nearly all circumstances.
ℹ If that’s really what you want, use an inline disable comment.
ℹ Safe fix: Use ‘number’ instead.
1 │ - let·invalidTuple:·[string,·Number]·=·[“foo”,·12];
1 │ + let·invalidTuple:·[string,·number]·=·[“foo”,·12];
2 2 │
function badFunction(cb: Function) { cb(12);}code-block.ts:1:26 lint/complexity/noBannedTypes ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Don’t use ‘Function’ as a type.
> 1 │ function badFunction(cb: Function) {
│ ^^^^^^^^
2 │ cb(12);
3 │ }
ℹ The ‘Function’ type is unsafe and accepts any arbitrary function or “function-like” value.
Explicitly defining the function’s shape helps prevent mismatching argument types and return values.
If a generic “catch-all” callback type is required, consider using a “top type” like ’(…args: never) => unknown’ instead.
ℹ If that’s really what you want, use an inline disable comment.
const notEmpty: {} = {prop: 12};code-block.ts:1:17 lint/complexity/noBannedTypes ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Don’t use ’{}’ as a type.
> 1 │ const notEmpty: {} = {prop: 12};
│ ^^
2 │
ℹ ’{}’ accepts any non-nullable value, including non-object primitives like ‘123’ and ‘true’.
- If you want a type meaning “any arbitrary object”, use ‘object’ instead.
- If you want a type meaning “any value”, use ‘unknown’ instead.
- If you want a type meaning “an object without any properties”, use ’{ [k: string]: never }’ or ‘Record<string, never>’ instead.
ℹ If that’s really what you want, use an inline disable comment.
const alsoNotAnObj: Object = "foo";code-block.ts:1:21 lint/complexity/noBannedTypes ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Don’t use ‘Object’ as a type.
> 1 │ const alsoNotAnObj: Object = “foo”;
│ ^^^^^^
2 │
ℹ ‘Object’ accepts any non-nullable value, including non-object primitives like ‘123’ and ‘true’.
- If you want a type meaning “any arbitrary object”, use ‘object’ instead.
- If you want a type meaning “any value”, use ‘unknown’ instead.
- If you want a type meaning “an object without any properties”, use ’{ [k: string]: never }’ or ‘Record<string, never>’ instead.
ℹ If that’s really what you want, use an inline disable comment.
const foo: string = "bar";let tuple: [boolean, string] = [false, "foo"];function betterFunction(cb: (n: number) => string) { return cb(12);}type wrapFn<T extends (...args: never) => unknown> = { func: T }const goodObj: object = {foo: 12};type emptyObj = Record<string, never>;Exceptions for {}:
declare function foo<T extends {}>(x: T): void;type notNull<T> = T & {};Related links
Section titled “Related links”Copyright (c) 2023-present Biome Developers and Contributors.