76 lines
3.6 KiB
Plaintext
76 lines
3.6 KiB
Plaintext
---
|
|
description: 'Disallow using confusing built-in primitive class wrappers.'
|
|
---
|
|
|
|
import Tabs from '@theme/Tabs';
|
|
import TabItem from '@theme/TabItem';
|
|
|
|
> 🛑 This file is source code, not the primary documentation location! 🛑
|
|
>
|
|
> See **https://typescript-eslint.io/rules/no-wrapper-object-types** for documentation.
|
|
|
|
TypeScript defines several confusing pairs of types that look very similar to each other, but actually mean different things: `boolean`/`Boolean`, `number`/`Number`, `string`/`String`, `bigint`/`BigInt`, `symbol`/`Symbol`, `object`/`Object`.
|
|
In general, only the lowercase variant is appropriate to use.
|
|
Therefore, this rule enforces that you only use the lowercase variant.
|
|
|
|
JavaScript has [8 data types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures) at runtime, and these are described in TypeScript by the lowercase types `undefined`, `null`, `boolean`, `number`, `string`, `bigint`, `symbol`, and `object`.
|
|
|
|
As for the uppercase types, these are _structural types_ which describe JavaScript "wrapper" objects for each of the data types, such as [`Boolean`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) and [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number).
|
|
Additionally, due to the quirks of structural typing, the corresponding primitives are _also_ assignable to these uppercase types, since they have the same "shape".
|
|
|
|
It is a universal best practice to work directly with the built-in primitives, like `0`, rather than objects that "look like" the corresponding primitive, like `new Number(0)`.
|
|
|
|
- Primitives have the expected value semantics with `==` and `===` equality checks, whereas their object counterparts are compared by reference.
|
|
That is to say, `"str" === "str"` but `new String("str") !== new String("str")`.
|
|
- Primitives have well-known behavior around truthiness/falsiness which is common to rely on, whereas all objects are truthy, regardless of the wrapped value (e.g. `new Boolean(false)` is truthy).
|
|
- TypeScript only allows arithmetic operations (e.g. `x - y`) to be performed on numeric primitives, not objects.
|
|
|
|
As a result, using the lowercase type names like `number` in TypeScript types instead of the uppercase names like `Number` is a better practice that describes code more accurately.
|
|
|
|
Examples of code for this rule:
|
|
|
|
<Tabs>
|
|
<TabItem value="❌ Incorrect">
|
|
|
|
```ts
|
|
let myBigInt: BigInt;
|
|
let myBoolean: Boolean;
|
|
let myNumber: Number;
|
|
let myString: String;
|
|
let mySymbol: Symbol;
|
|
|
|
let myObject: Object = 'allowed by TypeScript';
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="✅ Correct">
|
|
|
|
```ts
|
|
let myBigint: bigint;
|
|
let myBoolean: boolean;
|
|
let myNumber: number;
|
|
let myString: string;
|
|
let mySymbol: symbol;
|
|
|
|
let myObject: object = "Type 'string' is not assignable to type 'object'.";
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
## When Not To Use It
|
|
|
|
If your project is a rare one that intentionally deals with the class equivalents of primitives, it might not be worthwhile to use this rule.
|
|
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule.
|
|
|
|
## Further Reading
|
|
|
|
- [MDN documentation on primitives](https://developer.mozilla.org/en-US/docs/Glossary/Primitive)
|
|
- [MDN documentation on `string` primitives and `String` objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#string_primitives_and_string_objects)
|
|
|
|
## Related To
|
|
|
|
- [`no-empty-object-type`](./no-empty-object-type.mdx)
|
|
- [`ban-types`](./ban-types.mdx)
|
|
- [`no-unsafe-function-type`](./no-unsafe-function-type.mdx)
|