eslint-plugin-nextfriday 3.2.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +36 -70
- package/docs/agents/domain.md +51 -0
- package/docs/agents/issue-tracker.md +22 -0
- package/docs/agents/triage-labels.md +15 -0
- package/docs/rules/NO_GHOST_WRAPPER.md +75 -0
- package/docs/rules/NO_INLINE_NESTED_OBJECT.md +45 -27
- package/docs/rules/NO_REDUNDANT_FRAGMENT.md +56 -0
- package/docs/rules/PREFER_GUARD_CLAUSE.md +2 -0
- package/docs/rules/PREFER_IMPORT_TYPE.md +5 -0
- package/docs/rules/PREFER_INTERFACE_FOR_COMPONENT_PROPS.md +53 -0
- package/docs/rules/PREFER_NAMED_PARAM_TYPES.md +5 -1
- package/docs/rules/PREFER_PROPS_WITH_CHILDREN.md +112 -0
- package/lib/index.cjs +748 -679
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +176 -200
- package/lib/index.d.ts +176 -200
- package/lib/index.js +685 -616
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/docs/rules/ENFORCE_CURLY_NEWLINE.md +0 -55
- package/docs/rules/FILE_KEBAB_CASE.md +0 -70
- package/docs/rules/JSX_PASCAL_CASE.md +0 -71
- package/docs/rules/NEXTJS_REQUIRE_PUBLIC_ENV.md +0 -44
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# prefer-interface-for-component-props
|
|
2
|
+
|
|
3
|
+
Enforce `interface` over `type` alias for component prop declarations in component files (`*.tsx`, `*.jsx`).
|
|
4
|
+
|
|
5
|
+
> This rule is auto-fixable using `--fix`.
|
|
6
|
+
|
|
7
|
+
## Rule Details
|
|
8
|
+
|
|
9
|
+
In component files, prop declarations are more idiomatic as `interface` than `type` aliases. Interfaces support declaration merging, are easier to extend, and produce clearer error messages from the TypeScript compiler. This rule converts `type` aliases that look like component prop types into `interface` declarations.
|
|
10
|
+
|
|
11
|
+
The rule fires only when all of the following are true:
|
|
12
|
+
|
|
13
|
+
- The file extension is `.tsx` or `.jsx`
|
|
14
|
+
- The declaration is a `type` alias whose name ends with `Props`
|
|
15
|
+
- The body of the type is an object literal (`{ ... }`)
|
|
16
|
+
|
|
17
|
+
Type aliases with intersection types (`type FooProps = Other & { x: number }`), union types (`type Variant = 'a' | 'b'`), or non-object bodies (`type Props = ReactNode`) are left alone — they cannot be expressed as a single interface without restructuring.
|
|
18
|
+
|
|
19
|
+
## Examples
|
|
20
|
+
|
|
21
|
+
### Incorrect
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
type StorePopoverProps = {
|
|
25
|
+
trigger: ReactNode;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const StorePopover = (props: Readonly<StorePopoverProps>) => {
|
|
29
|
+
return <div>{props.trigger}</div>;
|
|
30
|
+
};
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Correct
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
interface StorePopoverProps {
|
|
37
|
+
trigger: ReactNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const StorePopover = (props: Readonly<StorePopoverProps>) => {
|
|
41
|
+
return <div>{props.trigger}</div>;
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## When Not To Use It
|
|
46
|
+
|
|
47
|
+
- If your codebase uses `type` aliases for component props by convention
|
|
48
|
+
- If you rely on type alias features that interfaces don't support (for example, intersections or unions in the same declaration)
|
|
49
|
+
|
|
50
|
+
## Related Rules
|
|
51
|
+
|
|
52
|
+
- [enforce-props-suffix](./ENFORCE_PROPS_SUFFIX.md) - Enforces the `Props` suffix that this rule keys off
|
|
53
|
+
- [prefer-interface-over-inline-types](./PREFER_INTERFACE_OVER_INLINE_TYPES.md) - Sister rule for inline types in component params
|
|
@@ -89,6 +89,10 @@ const setup = (config: Config) => {
|
|
|
89
89
|
};
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
+
## Exceptions
|
|
93
|
+
|
|
94
|
+
This rule defers to [`prefer-interface-over-inline-types`](./PREFER_INTERFACE_OVER_INLINE_TYPES.md) for React components with a single non-destructured prop parameter (for example, `function Comp(props: { name: string }) { return <div /> }`). Both rules would otherwise report the same parameter with different messages, so `prefer-named-param-types` skips that case and lets the React-specific rule produce the canonical message. Destructured component props (`function Comp({ name }: { name: string })`) and non-component functions are still reported here.
|
|
95
|
+
|
|
92
96
|
## When Not To Use It
|
|
93
97
|
|
|
94
98
|
- If you prefer inline types for simple, one-off function parameters
|
|
@@ -97,4 +101,4 @@ const setup = (config: Config) => {
|
|
|
97
101
|
|
|
98
102
|
## Related Rules
|
|
99
103
|
|
|
100
|
-
- [prefer-interface-over-inline-types](./PREFER_INTERFACE_OVER_INLINE_TYPES.md) -
|
|
104
|
+
- [prefer-interface-over-inline-types](./PREFER_INTERFACE_OVER_INLINE_TYPES.md) - Owns React component non-destructured prop case
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# prefer-props-with-children
|
|
2
|
+
|
|
3
|
+
Prefer `PropsWithChildren<T>` over manually declaring `children: ReactNode` in component props.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
This rule reports interfaces, type aliases, and inline parameter types that declare a `children` field typed as `ReactNode` (or `React.ReactNode`). React already provides the `PropsWithChildren<T>` helper for this exact case, so prefer it for consistency and to avoid restating the well-known `children` shape on every component.
|
|
8
|
+
|
|
9
|
+
The rule only flags `children` whose type is exactly `ReactNode` (matching what `PropsWithChildren` provides). Other shapes such as `ReactElement`, render-prop functions, or unions like `ReactNode | string` are left alone.
|
|
10
|
+
|
|
11
|
+
### Why?
|
|
12
|
+
|
|
13
|
+
- `PropsWithChildren<T>` is the canonical type for components that accept children, making intent obvious at a glance.
|
|
14
|
+
- It eliminates duplication of the `children` declaration across every component that accepts children.
|
|
15
|
+
- It keeps the surrounding props focused on what is unique to the component.
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
|
|
19
|
+
### Incorrect
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
interface LayoutProps {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
interface CardProps {
|
|
29
|
+
title: string;
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
interface OptionalChildrenProps {
|
|
36
|
+
children?: ReactNode;
|
|
37
|
+
label: string;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
interface ReactNamespaceProps {
|
|
43
|
+
children: React.ReactNode;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
type WrapperProps = {
|
|
49
|
+
children: ReactNode;
|
|
50
|
+
className: string;
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
const Component = ({ children, label }: { children: ReactNode; label: string }) => (
|
|
56
|
+
<div>
|
|
57
|
+
{children}
|
|
58
|
+
{label}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Correct
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
type LayoutProps = PropsWithChildren;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
interface CardProps extends PropsWithChildren {
|
|
71
|
+
title: string;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
type WrapperProps = PropsWithChildren<{
|
|
77
|
+
className: string;
|
|
78
|
+
}>;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
const Component = (props: Readonly<PropsWithChildren<{ label: string }>>) => (
|
|
83
|
+
<div>
|
|
84
|
+
{props.children}
|
|
85
|
+
{props.label}
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
interface RenderProps {
|
|
92
|
+
children: (value: string) => ReactNode;
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
interface SlotProps {
|
|
98
|
+
children: ReactElement;
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## When Not To Use It
|
|
103
|
+
|
|
104
|
+
This rule should not be used if:
|
|
105
|
+
|
|
106
|
+
- Your project intentionally avoids `PropsWithChildren` and prefers explicit `children` declarations.
|
|
107
|
+
- You frequently use children types other than `ReactNode` (this rule already skips those cases).
|
|
108
|
+
|
|
109
|
+
## Related Rules
|
|
110
|
+
|
|
111
|
+
- [`prefer-react-import-types`](./PREFER_REACT_IMPORT_TYPES.md) - Enforce direct imports from `react` instead of `React.X`
|
|
112
|
+
- [`enforce-props-suffix`](./ENFORCE_PROPS_SUFFIX.md) - Enforce `Props` suffix for component prop types
|