[ { "code": "adjacent-overload-signatures", "docs": "Requires overload signatures to be adjacent to each other.\n\nOverloaded signatures which are not next to each other can lead to code which is\nhard to read and maintain.\n\n### Invalid:\n\n(`bar` is declared in-between `foo` overloads)\n\n```typescript\ntype FooType = {\n foo(s: string): void;\n foo(n: number): void;\n bar(): void;\n foo(sn: string | number): void;\n};\n```\n\n```typescript\ninterface FooInterface {\n foo(s: string): void;\n foo(n: number): void;\n bar(): void;\n foo(sn: string | number): void;\n}\n```\n\n```typescript\nclass FooClass {\n foo(s: string): void;\n foo(n: number): void;\n bar(): void {}\n foo(sn: string | number): void {}\n}\n```\n\n```typescript\nexport function foo(s: string): void;\nexport function foo(n: number): void;\nexport function bar(): void {}\nexport function foo(sn: string | number): void {}\n```\n\n### Valid:\n\n(`bar` is declared after `foo`)\n\n```typescript\ntype FooType = {\n foo(s: string): void;\n foo(n: number): void;\n foo(sn: string | number): void;\n bar(): void;\n};\n```\n\n```typescript\ninterface FooInterface {\n foo(s: string): void;\n foo(n: number): void;\n foo(sn: string | number): void;\n bar(): void;\n}\n```\n\n```typescript\nclass FooClass {\n foo(s: string): void;\n foo(n: number): void;\n foo(sn: string | number): void {}\n bar(): void {}\n}\n```\n\n```typescript\nexport function foo(s: string): void;\nexport function foo(n: number): void;\nexport function foo(sn: string | number): void {}\nexport function bar(): void {}\n```\n", "tags": [ "recommended" ] }, { "code": "ban-ts-comment", "docs": "Disallows the use of Typescript directives without a comment.\n\nTypescript directives reduce the effectiveness of the compiler, something which\nshould only be done in exceptional circumstances. The reason why should be\ndocumented in a comment alongside the directive.\n\n### Invalid:\n\n```typescript\n// @ts-expect-error\nlet a: number = \"I am a string\";\n```\n\n```typescript\n// @ts-ignore\nlet a: number = \"I am a string\";\n```\n\n```typescript\n// @ts-nocheck\nlet a: number = \"I am a string\";\n```\n\n### Valid:\n\n```typescript\n// @ts-expect-error: Temporary workaround (see ticket #422)\nlet a: number = \"I am a string\";\n```\n\n```typescript\n// @ts-ignore: Temporary workaround (see ticket #422)\nlet a: number = \"I am a string\";\n```\n\n```typescript\n// @ts-nocheck: Temporary workaround (see ticket #422)\nlet a: number = \"I am a string\";\n```\n", "tags": [ "recommended" ] }, { "code": "ban-types", "docs": "Bans the use of primitive wrapper objects (e.g. `String` the object is a wrapper\nof `string` the primitive) in addition to the non-explicit `Function` type and\nthe misunderstood `Object` type.\n\nThere are very few situations where primitive wrapper objects are desired and\nfar more often a mistake was made with the case of the primitive type. You also\ncannot assign a primitive wrapper object to a primitive leading to type issues\ndown the line. For reference, [the TypeScript handbook] also says we shouldn't\never use these wrapper objects.\n\n[the TypeScript handbook]: https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#number-string-boolean-symbol-and-object\n\nWith `Function`, it is better to explicitly define the entire function signature\nrather than use the non-specific `Function` type which won't give you type\nsafety with the function.\n\nFinally, `Object` and `{}` means \"any non-nullish value\" rather than \"any object\ntype\". `object` is a good choice for a meaning of \"any object type\".\n\n### Invalid:\n\n```typescript\nlet a: Boolean;\nlet b: String;\nlet c: Number;\nlet d: Symbol;\nlet e: Function;\nlet f: Object;\nlet g: {};\n```\n\n### Valid:\n\n```typescript\nlet a: boolean;\nlet b: string;\nlet c: number;\nlet d: symbol;\nlet e: () => number;\nlet f: object;\nlet g: Record;\n```\n", "tags": [ "recommended" ] }, { "code": "ban-unknown-rule-code", "docs": "Warns the usage of unknown rule codes in ignore directives\n\nWe sometimes have to suppress and ignore lint errors for some reasons. We can do\nso using [ignore directives](https://lint.deno.land/ignoring-rules) with rule\nnames that should be ignored like so:\n\n```typescript\n// deno-lint-ignore no-explicit-any no-unused-vars\nconst foo: any = 42;\n```\n\nThis rule checks for the validity of the specified rule names (i.e. whether\n`deno_lint` provides the rule or not).\n\n### Invalid:\n\n```typescript\n// typo\n// deno-lint-ignore eq-eq-e\nconsole.assert(x == 42);\n\n// unknown rule name\n// deno-lint-ignore UNKNOWN_RULE_NAME\nconst b = \"b\";\n```\n\n### Valid:\n\n```typescript\n// deno-lint-ignore eq-eq-eq\nconsole.assert(x == 42);\n\n// deno-lint-ignore no-unused-vars\nconst b = \"b\";\n```\n", "tags": [ "recommended" ] }, { "code": "ban-untagged-ignore", "docs": "Requires `deno-lint-ignore` to be annotated with one or more rule names.\n\nIgnoring all rules can mask unexpected or future problems. Therefore you need to\nexplicitly specify which rule(s) are to be ignored.\n\n### Invalid:\n\n```typescript\n// deno-lint-ignore\nexport function duplicateArgumentsFn(a, b, a) {}\n```\n\n### Valid:\n\n```typescript\n// deno-lint-ignore no-dupe-args\nexport function duplicateArgumentsFn(a, b, a) {}\n```\n", "tags": [ "recommended" ] }, { "code": "ban-untagged-todo", "docs": "Requires TODOs to be annotated with either a user tag (`@user`) or an issue\nreference (`#issue`).\n\nTODOs without reference to a user or an issue become stale with no easy way to\nget more information.\n\n### Invalid:\n\n```typescript\n// TODO Improve calc engine\nexport function calcValue(): number {}\n```\n\n```typescript\n// TODO Improve calc engine (@djones)\nexport function calcValue(): number {}\n```\n\n```typescript\n// TODO Improve calc engine (#332)\nexport function calcValue(): number {}\n```\n\n### Valid:\n\n```typescript\n// TODO(djones) Improve calc engine\nexport function calcValue(): number {}\n```\n\n```typescript\n// TODO(@djones) Improve calc engine\nexport function calcValue(): number {}\n```\n\n```typescript\n// TODO(#332)\nexport function calcValue(): number {}\n```\n\n```typescript\n// TODO(#332) Improve calc engine\nexport function calcValue(): number {}\n```\n", "tags": [] }, { "code": "ban-unused-ignore", "docs": "Warns unused ignore directives\n\nWe sometimes have to suppress and ignore lint errors for some reasons and we can\ndo so using [ignore directives](https://lint.deno.land/ignoring-rules).\n\nIn some cases, however, like after refactoring, we may end up having ignore\ndirectives that are no longer necessary. Such superfluous ignore directives are\nlikely to confuse future code readers, and to make matters worse, might hide\nfuture lint errors unintentionally. To prevent such situations, this rule\ndetects unused, superfluous ignore directives.\n\n### Invalid:\n\n```typescript\n// Actually this line is valid since `export` means \"used\",\n// so this directive is superfluous\n// deno-lint-ignore no-unused-vars\nexport const foo = 42;\n```\n\n### Valid:\n\n```typescript\nexport const foo = 42;\n```\n", "tags": [ "recommended" ] }, { "code": "button-has-type", "docs": "Checks that a `;\n}\n\n// BAD: Called inside useMemo\nfunction Component() {\n const value = useMemo(() => {\n const [count, setCount] = useState(0);\n return count;\n });\n}\n\n// BAD: Called inside try/catch\nfunction Component() {\n try {\n const [count, setCount] = useState(0);\n } catch {\n const [count, setCount] = useState(0);\n }\n\n // ...\n}\n```\n\n### Valid:\n\n```tsx\nfunction Component() {\n const [count, setCount] = useState(0);\n // ...\n}\n\nfunction useCustomHook() {\n const [count, setCount] = useState(0);\n // ...\n}\n```\n", "tags": [ "recommended", "react", "jsx", "fresh" ] }, { "code": "single-var-declarator", "docs": "Disallows multiple variable definitions in the same declaration statement\n\n### Invalid:\n\n```typescript\nconst foo = 1, bar = \"2\";\n```\n\n### Valid:\n\n```typescript\nconst foo = 1;\nconst bar = \"2\";\n```\n", "tags": [] }, { "code": "triple-slash-reference", "docs": "Disallow certain triple slash directives in favor of ES6-style import\ndeclarations\n\nTypeScript's `///` triple-slash references are a way to indicate that types from\nanother module are available in a file. Use of triple-slash reference type\ndirectives is generally discouraged in favor of ECMAScript Module imports. This\nrule reports on the use of `/// `,\n`/// `, or `/// ` directives.\n\n### Invalid:\n\n```typescript\n/// \nimport * as foo from \"foo\";\n```\n\n### Valid:\n\n```typescript\nimport * as foo from \"foo\";\n```\n", "tags": [] }, { "code": "use-isnan", "docs": "Disallows comparisons to `NaN`.\n\nBecause `NaN` is unique in JavaScript by not being equal to anything, including\nitself, the results of comparisons to `NaN` are confusing:\n\n- `NaN === NaN` or `NaN == NaN` evaluate to `false`\n- `NaN !== NaN` or `NaN != NaN` evaluate to `true`\n\nTherefore, this rule makes you use the `isNaN()` or `Number.isNaN()` to judge\nthe value is `NaN` or not.\n\n### Invalid:\n\n```typescript\nif (foo == NaN) {\n // ...\n}\n\nif (foo != NaN) {\n // ...\n}\n\nswitch (NaN) {\n case foo:\n // ...\n}\n\nswitch (foo) {\n case NaN:\n // ...\n}\n```\n\n### Valid:\n\n```typescript\nif (isNaN(foo)) {\n // ...\n}\n\nif (!isNaN(foo)) {\n // ...\n}\n```\n", "tags": [ "recommended" ] }, { "code": "valid-typeof", "docs": "Restricts the use of the `typeof` operator to a specific set of string literals.\n\nWhen used with a value the `typeof` operator returns one of the following\nstrings:\n\n- `\"undefined\"`\n- `\"object\"`\n- `\"boolean\"`\n- `\"number\"`\n- `\"string\"`\n- `\"function\"`\n- `\"symbol\"`\n- `\"bigint\"`\n\nThis rule disallows comparison with anything other than one of these string\nliterals when using the `typeof` operator, as this likely represents a typing\nmistake in the string. The rule also disallows comparing the result of a\n`typeof` operation with any non-string literal value, such as `undefined`, which\ncan represent an inadvertent use of a keyword instead of a string. This includes\ncomparing against string variables even if they contain one of the above values\nas this cannot be guaranteed. An exception to this is comparing the results of\ntwo `typeof` operations as these are both guaranteed to return on of the above\nstrings.\n\n### Invalid:\n\n```typescript\n// typo\ntypeof foo === \"strnig\";\ntypeof foo == \"undefimed\";\ntypeof bar != \"nunber\";\ntypeof bar !== \"fucntion\";\n\n// compare with non-string literals\ntypeof foo === undefined;\ntypeof bar == Object;\ntypeof baz === anotherVariable;\ntypeof foo == 5;\n```\n\n### Valid:\n\n```typescript\ntypeof foo === \"undefined\";\ntypeof bar == \"object\";\ntypeof baz === \"string\";\ntypeof bar === typeof qux;\n```\n", "tags": [ "recommended" ] }, { "code": "verbatim-module-syntax", "docs": "Enforces type imports to be declared as type imports.\n\nThis rule ensures that the code works when the `verbatimModuleSyntax` TypeScript\ncompiler option is enabled. This is useful in libraries distributing TypeScript\ncode in order to work in more scenarios.\n\n### Invalid:\n\n```typescript\nimport { Person } from \"./person.ts\";\n\nconst person: Person = {\n name: \"David\",\n};\nconsole.log(person);\n```\n\n```typescript\nimport { output, Person } from \"./person.ts\";\n\nconst person: Person = {\n name: \"David\",\n};\noutput(person);\n```\n\n### Valid:\n\n```typescript\nimport type { Person } from \"./person.ts\";\n\nconst person: Person = {\n name: \"David\",\n};\nconsole.log(person);\n```\n\n```typescript\nimport { output, type Person } from \"./person.ts\";\n\nconst person: Person = {\n name: \"David\",\n};\noutput(person);\n```\n", "tags": [ "jsr" ] } ]