Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0aa09e1

Browse files
committed
feat: update docs, and config
1 parent dd16faf commit 0aa09e1

File tree

3 files changed

+69
-35
lines changed

3 files changed

+69
-35
lines changed

packages/eslint-plugin/docs/rules/ban-types.md

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,34 @@ class Foo<F = string> extends Bar<string> implements Baz<string> {
3131

3232
## Options
3333

34-
The banned type can either be a type name literal (`Foo`), a type name with generic parameter instantiations(s) (`Foo<Bar>`), or the empty object literal (`{}`).
34+
```ts
35+
type Options = {
36+
types: {
37+
[typeName: string]:
38+
| string
39+
| {
40+
message: string;
41+
fixWith?: string;
42+
};
43+
};
44+
};
45+
```
46+
47+
The rule accepts a single object as options, with the key `types`.
3548

36-
```CJSON
49+
- The keys should match the types you want to ban. The type can either be a type name literal (`Foo`), a type name with generic parameter instantiations(s) (`Foo<Bar>`), or the empty object literal (`{}`).
50+
- The value can be an object with the following properties:
51+
- `message: string` - the message to display when the type is matched.
52+
- `fixWith?: string` - a string to replace the banned type with when the fixer is run. If this is omitted, no fix will be done.
53+
54+
### Example config
55+
56+
```JSONC
3757
{
3858
"@typescript-eslint/ban-types": ["error", {
3959
"types": {
40-
// report usages of the type using the default error message
41-
"Foo": null,
42-
4360
// add a custom message to help explain why not to use it
44-
"Bar": "Don't use bar!",
61+
"Foo": "Don't use bar!",
4562

4663
// add a custom message, AND tell the plugin how to fix it
4764
"String": {
@@ -58,25 +75,20 @@ The banned type can either be a type name literal (`Foo`), a type name with gene
5875
}
5976
```
6077

61-
### Example
78+
### Default Options
6279

63-
```json
64-
{
65-
"@typescript-eslint/ban-types": [
66-
"error",
67-
{
68-
"types": {
69-
"Array": null,
70-
"Object": "Use {} instead",
71-
"String": {
72-
"message": "Use string instead",
73-
"fixWith": "string"
74-
}
75-
}
76-
}
77-
]
78-
}
79-
```
80+
The default options provides a set of "best practices", intended to provide safety and standardization in your codebase:
81+
82+
- Don't use the upper case primitive types, you should use the lower-case types for consistency.
83+
- Avoid the `Function` type, as it provides little safety for the following reasons:
84+
- It provides no type-safety when calling the value, which means it's easy to provide the wrong arguments.
85+
- It accepts class declarations, which will fail when called, as they are called without the `new` keyword.
86+
- Avoid the `Object` and `{}` types, as they means "any non-nullish value".
87+
- This is a point of confusion for many developers, who think it means "any object type".
88+
- Avoid the `object`, as it is currently hard to use due to not being able to assert that keys exist.
89+
- See [microsoft/TypeScript#21732](https://github.com/microsoft/TypeScript/issues/21732).
90+
91+
**_Important note:_** the default options suggests using `Record<string, unknown>`; this was a stylistic decision, as the built-in `Record` type is considered to look cleaner.
8092

8193
## Compatibility
8294

packages/eslint-plugin/src/rules/ban-types.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export default util.createRule<Options, MessageIds>({
8989
defaultOptions: [
9090
{
9191
types: {
92+
// use lower-case instead
9293
String: {
9394
message: 'Use string instead',
9495
fixWith: 'string',
@@ -101,19 +102,41 @@ export default util.createRule<Options, MessageIds>({
101102
message: 'Use number instead',
102103
fixWith: 'number',
103104
},
104-
Object: {
105-
message:
106-
'The Object type is mostly the same as unknown, you probably want Record<string, unknown> instead'
107-
},
108-
object: {
109-
message:
110-
'The object type is hard to use, use Record<string, unknown> instead',
111-
fixWith: 'Record<string, unknown>'
112-
},
113105
Symbol: {
114106
message: 'Use symbol instead',
115107
fixWith: 'symbol',
116108
},
109+
110+
Function: {
111+
message: [
112+
'The `Function` type accepts any function-like value.',
113+
'It provides no type-safety when calling the function, which can be a common source of bugs.',
114+
'It also accepts things like class declarations, which will throw at runtime as they will not be called with `new`.',
115+
'If you are expecting the function to accept certain arguments, you should explicitly define function shape.',
116+
].join('\n'),
117+
},
118+
119+
// object typing
120+
Object: {
121+
message: [
122+
'The `Object` type actually means "any non-nullish value", so it is marginally better than `unknown`.',
123+
'- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.',
124+
'- If you want a type meaning "any value", you probably want `unknown` instead.',
125+
].join('\n'),
126+
},
127+
'{}': {
128+
message: [
129+
'`{}` actually means "any non-nullish value".',
130+
'- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.',
131+
'- If you want a type meaning "any value", you probably want `unknown` instead.',
132+
].join('\n'),
133+
},
134+
object: {
135+
message: [
136+
'The `object` type is currently hard to use (see https://github.com/microsoft/TypeScript/issues/21732).',
137+
'Consider using `Record<string, unknown>` instead, as it allows you to more easily inspect and use the keys.',
138+
].join('\n'),
139+
},
117140
},
118141
},
119142
],

packages/eslint-plugin/tests/rules/ban-types.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ const options: InferOptionsTypeFromRule<typeof rule> = [
2626

2727
ruleTester.run('ban-types', rule, {
2828
valid: [
29-
'let f = Object();', // Should not fail if there is no options set
30-
'let f: {} = {};',
29+
'let f = Object();', // Should not fail, as it is not a type position
3130
'let f: { x: number, y: number } = { x: 1, y: 1 };',
3231
{
3332
code: 'let f = Object();',

0 commit comments

Comments
 (0)