A collection of useful ESLint tricks
To enforce the component type of all children in a specific component, use the no-restricted-syntax
built-in rule:
eslint.config.js
import tseslint from 'typescript-eslint';
export default tseslint.config({
rules: {
'no-restricted-syntax': [
'warn',
{
selector:
"JSXElement[openingElement.name.name='List'] JSXElement:not([openingElement.name.name='ListItem'])",
message:
'The List component must contain only <ListItem /> elements as children',
},
],
},
});
Examples of incorrect code for this rule config:
<List>
<div />
<ListItem />
</List>
Examples of correct code for this rule config:
<List>
<ListItem />
<ListItem />
</List>
To enforce both the component type and order of children in a specific component, use the no-restricted-syntax
built-in rule and reference the index of the children by odd numbers starting at 1
(1
is first child, 3
is second child, 5
is third child, etc):
eslint.config.js
import tseslint from 'typescript-eslint';
export default tseslint.config({
rules: {
'no-restricted-syntax': [
'warn',
{
selector:
"JSXElement[openingElement.name.name='TwoColumnLayout']:not([children.1.openingElement.name.name='Meta']), JSXElement[openingElement.name.name='TwoColumnLayout']:not([children.3.openingElement.name.name='main']), JSXElement[openingElement.name.name='TwoColumnLayout']:not([children.5.openingElement.name.name='aside'])",
message:
'The TwoColumLayout component must contain only <Meta />, <main> and <aside> elements as children, in exactly this order',
},
],
},
});
Examples of incorrect code for this rule config:
<TwoColumnLayout/>
<TwoColumnLayout>
</TwoColumnLayout>
<TwoColumnLayout>
<main />
<aside />
</TwoColumnLayout>
Examples of correct code for this rule config:
<TwoColumnLayout>
<Meta />
<main />
<aside />
</TwoColumnLayout>