Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions apps/website/content/docs/configurations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ For example, if you are using `@pika/react` instead of `react`, you can set the
import React from "@pika/react";
```

### `strictImportCheck`
### `skipImportCheck`

Check both the shape and the import to determine if an API is from React before applying the rules.
When determining whether an API originates from React, bypass the import source check.

This can prevent false positives when using a irrelevant third-party library that has similar APIs to React.
By default, the rule checks only the shape of the API to determine if it is a React API. If `skipImportCheck` is set to `false`, the rule will check both the shape and the import source.

For example, if you set the `strictImportCheck` to `true`, then the `memo` function from `irrelevant-library` will not be recognized as React's `memo`:
For example, when `skipImportCheck` is set to false, the `memo` function from `unrelated-library` will not be recognized as React's `memo`.

```ts
import { memo } from "irrelevant-library";
import { memo } from "unrelated-library";

const NonComponentFunction = memo(() => {
// ^^^^
Expand Down
6 changes: 3 additions & 3 deletions apps/website/content/docs/configurations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ export function SettingsTypeTable() {
description: <Link href="#importsource">The source where React is imported from ⤵</Link>,
default: "react",
},
strictImportCheck: {
skipImportCheck: {
type: "boolean",
description: (
<Link href="#strictimportcheck">
<Link href="#skipImportCheck">
Check both the shape and the import to determine if an API is from React before applying the rules. ⤵
</Link>
),
default: "false",
default: "true",
},
polymorphicPropName: {
type: "string",
Expand Down
29 changes: 13 additions & 16 deletions packages/core/src/hook/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { unsafeDecodeSettings } from "@eslint-react/shared";
import type { TSESTree } from "@typescript-eslint/types";
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";

import { DEFAULT_ESLINT_REACT_SETTINGS } from "../../../shared/src/schemas";
import { isInitializedFromReact } from "../utils";
import { isReactHookName } from "./hook-name";

Expand Down Expand Up @@ -35,23 +36,21 @@ export function isReactHookCall(node: TSESTree.Node | _) {

export function isReactHookCallWithName(context: RuleContext, node: TSESTree.CallExpression | _) {
if (node == null) return constFalse;
const settings = unsafeDecodeSettings(context.settings);
const importSource = settings.importSource ?? "react";
const {
importSource = DEFAULT_ESLINT_REACT_SETTINGS.importSource,
skipImportCheck = true,
} = unsafeDecodeSettings(context.settings);
const initialScope = context.sourceCode.getScope(node);
return (name: string) => {
switch (true) {
case node.callee.type === T.Identifier
&& node.callee.name === name:
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
return !settings.strictImportCheck
|| isInitializedFromReact(name, importSource, initialScope);
return skipImportCheck || isInitializedFromReact(name, importSource, initialScope);
case node.callee.type === T.MemberExpression
&& node.callee.property.type === T.Identifier
&& node.callee.property.name === name
&& "name" in node.callee.object:
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
return !settings.strictImportCheck
|| isInitializedFromReact(node.callee.object.name, importSource, initialScope);
return skipImportCheck || isInitializedFromReact(node.callee.object.name, importSource, initialScope);
default:
return false;
}
Expand All @@ -73,23 +72,21 @@ export function isReactHookCallWithNameLoose(node: TSESTree.CallExpression | _)
}

export function isReactHookCallWithNameAlias(context: RuleContext, name: string, alias: string[]) {
const settings = unsafeDecodeSettings(context);
const importSource = settings.importSource ?? "react";
const {
importSource = DEFAULT_ESLINT_REACT_SETTINGS.importSource,
skipImportCheck = true,
} = unsafeDecodeSettings(context.settings);
return (node: TSESTree.CallExpression) => {
const initialScope = context.sourceCode.getScope(node);
switch (true) {
case node.callee.type === T.Identifier
&& node.callee.name === name:
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
return !settings.strictImportCheck
|| isInitializedFromReact(name, importSource, initialScope);
return skipImportCheck || isInitializedFromReact(name, importSource, initialScope);
case node.callee.type === T.MemberExpression
&& node.callee.property.type === T.Identifier
&& node.callee.property.name === name
&& "name" in node.callee.object:
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
return !settings.strictImportCheck
|| isInitializedFromReact(node.callee.object.name, importSource, initialScope);
return skipImportCheck || isInitializedFromReact(node.callee.object.name, importSource, initialScope);
default:
return alias.some(isReactHookCallWithNameLoose(node));
}
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/utils/is-from-react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export function isFromReactStrict(

export function isFromReact(name: string) {
return (context: RuleContext, node: TSESTree.Identifier | TSESTree.MemberExpression) => {
const { importSource = defaultImportSource, strictImportCheck = false } = unsafeDecodeSettings(context.settings);
if (!strictImportCheck) return isFromReactLoose(node, name);
const { importSource = defaultImportSource, skipImportCheck = true } = unsafeDecodeSettings(context.settings);
if (skipImportCheck) return isFromReactLoose(node, name);
return isFromReactStrict(node, name, importSource, context.sourceCode.getScope(node));
};
}
Expand Down Expand Up @@ -88,8 +88,8 @@ export function isFromReactMemberStrict(

export function isFromReactMember(memberName: string, name: string) {
return (context: RuleContext, node: TSESTree.MemberExpression) => {
const { importSource = defaultImportSource, strictImportCheck = false } = unsafeDecodeSettings(context.settings);
if (!strictImportCheck) return isFromReactMemberLoose(node, memberName, name);
const { importSource = defaultImportSource, skipImportCheck = true } = unsafeDecodeSettings(context.settings);
if (skipImportCheck) return isFromReactMemberLoose(node, memberName, name);
return isFromReactMemberStrict(node, memberName, name, importSource, context.sourceCode.getScope(node));
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -45,7 +44,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -66,7 +64,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -85,7 +82,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -107,7 +103,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -132,7 +127,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -154,7 +148,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -171,7 +164,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -189,7 +181,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -210,7 +201,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -229,7 +219,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -251,7 +240,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand Down Expand Up @@ -282,7 +270,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "@pika/react",
strictImportCheck: true,
},
},
},
Expand All @@ -302,7 +289,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "react",
strictImportCheck: true,
},
},
},
Expand All @@ -322,7 +308,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "react",
strictImportCheck: true,
},
},
},
Expand All @@ -336,7 +321,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "react",
strictImportCheck: true,
},
},
},
Expand All @@ -348,7 +332,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "react",
strictImportCheck: true,
},
},
},
Expand All @@ -360,7 +343,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "react",
strictImportCheck: true,
},
},
},
Expand All @@ -372,7 +354,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "react",
strictImportCheck: true,
},
},
},
Expand All @@ -386,7 +367,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "react",
strictImportCheck: true,
},
},
},
Expand All @@ -402,7 +382,6 @@ ruleTester.run(RULE_NAME, rule, {
settings: {
"react-x": {
importSource: "react",
strictImportCheck: true,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ ruleTester.run(RULE_NAME, rule, {
}],
settings: {
"react-x": {
strictImportCheck: false,
skipImportCheck: true,
},
},
},
Expand Down Expand Up @@ -159,7 +159,7 @@ ruleTester.run(RULE_NAME, rule, {
`,
settings: {
"react-x": {
strictImportCheck: true,
skipImportCheck: false,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ ruleTester.run(RULE_NAME, rule, {
`,
settings: {
"react-x": {
strictImportCheck: true,
skipImportCheck: false,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ ruleTester.run(RULE_NAME, rule, {
`,
settings: {
"react-x": {
strictImportCheck: true,
skipImportCheck: false,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ ruleTester.run(RULE_NAME, rule, {
`,
settings: {
"react-x": {
strictImportCheck: true,
skipImportCheck: false,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ ruleTester.run(RULE_NAME, rule, {
`,
settings: {
"react-x": {
strictImportCheck: true,
skipImportCheck: false,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ ruleTester.run(RULE_NAME, rule, {
`,
settings: {
"react-x": {
strictImportCheck: true,
skipImportCheck: false,
},
},
},
Expand Down
10 changes: 5 additions & 5 deletions packages/shared/docs/functions/defineSettings.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ This is used to determine the type of the component.
`"as"`
```

#### strictImportCheck
#### skipImportCheck

`boolean` = `...`

Expand All @@ -200,7 +200,7 @@ This can prevent false positives when using a irrelevant third-party library tha

**Default**

`false`
`true`

#### version?

Expand Down Expand Up @@ -397,9 +397,9 @@ This is used to determine the type of the component.
`"as"`
```

### strictImportCheck
### skipImportCheck

> **strictImportCheck**: `boolean`
> **skipImportCheck**: `boolean`

Check both the shape and the import to determine if an API is from React.

Expand All @@ -409,7 +409,7 @@ This can prevent false positives when using a irrelevant third-party library tha

#### Default

`false`
`true`

### version?

Expand Down
Loading