biome-plugin-react-use-propswithchildren
v1.0.0
Published
Biome GritQL plugin: require components that use children to type their props via PropsWithChildren<Props>, and disallow declaring children explicitly inside Props
Maintainers
Readme
biome-plugin-react-use-propswithchildren
A Biome GritQL plugin that requires
components that use children to type their props via React's own PropsWithChildren<Props>
generic, and disallows declaring children explicitly as a field inside Props. This is the
GritQL-plugin counterpart of
eslint-plugin-react-use-propswithchildren, for
projects that lint with Biome instead of ESLint.
Rule
require-props-with-children.grit
Flags a component (arrow function, function expression, or function declaration) that returns
JSX and destructures children from its props parameter, in three directions:
- Missing PropsWithChildren —
childrenis destructured, but the parameter's type isn'tPropsWithChildren<...>/React.PropsWithChildren<...>. - Explicit children in Props — the props type (inline object literal, or a same-file named
type/interface, including the T ofPropsWithChildren<T>) declareschildrenas its own field. - Unnecessary PropsWithChildren — the props type is
PropsWithChildren<...>, butchildrenis never destructured.
Installation
npm install biome-plugin-react-use-propswithchildren --save-devRegister the plugin in biome.json/biome.jsonc:
{
"plugins": [
"./node_modules/biome-plugin-react-use-propswithchildren/require-props-with-children.grit",
],
}Or copy biome.jsonc from this package as a starting point.
Requires Biome 2.0+ (GritQL plugin support). Diagnostics-only (no autofix).
Limitations
GritQL has no type checker — it reads TS type syntax structurally. children usage is detected
as a children binding inside the destructured parameter (JsObjectBindingPattern); the
non-destructured props.children member-access shape (supported by the ESLint/oxlint packages)
isn't attempted here, since GritQL's contains has no clean way to scope "somewhere in the
function body, but only as <paramName>.children" without the parameter's name as a join key.
Known GritQL runtime limitation, not fixed: the plugin's top-level or only reports the
first matching alternative for a given declaration, even when more than one alternative would
independently match (confirmed by isolated testing against Biome 2.5.5 — the same class of
or/contains runtime gotcha documented in the sibling
biome-plugin-react-memo-primitives
package). Concretely: a component that both lacks PropsWithChildren and declares
children explicitly inside its props type only reports "missing PropsWithChildren" (listed
first in the .grit file, since fixing the missing wrapper is the more foundational issue) — it
does not also report "explicit children in Props" for that same declaration. Fixing the first
diagnostic and re-running the linter will then surface the second, since after wrapping in
PropsWithChildren<Props> the explicit-children-in-Props violation becomes the only remaining
match. "Explicit children in Props" fires normally on its own whenever PropsWithChildren is
already used but its own type argument still declares children.
A type alias imported from elsewhere, or a generic type parameter, can't be resolved from a single file's AST — the "explicit children in Props" check simply doesn't fire for those, since there's no local declaration to inspect.
Biome resolves a plugin's relative path against the config file's own directory, so a config
written into a nested directory needs a ../-relative plugin path, or should sit next to the
.grit file (as biome.jsonc in this package does).
Testing
npm testRuns the local biome binary against the fixture in test/fixtures/ (test/run.js) and asserts
diagnostics land on exactly the expected lines. There's no RuleTester-equivalent for GritQL
plugins — this shells out to the real Biome CLI, since that's the only way to validate GritQL
syntax actually compiles and matches as intended.
