Skip to content

Instantly share code, notes, and snippets.

@dartess
Created August 4, 2023 12:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dartess/615fd442461db793a417def8e5060681 to your computer and use it in GitHub Desktop.
Save dartess/615fd442461db793a417def8e5060681 to your computer and use it in GitHub Desktop.
eslint-plugin
/**
* @fileoverview The default export should include type checking using `satisfy Meta`
* @author Sergey Kozlov
*/
"use strict";
module.exports = {
/**
* @type { import('eslint').Rule.RuleMetaData }
*/
meta: {
type: "suggestion",
docs: {
description: "The default export should include type checking using `satisfy Meta`",
recommended: false,
},
messages: {
exportDefaultTypeCheck: "`export default` should be `satisfies Meta<typeof T>`",
},
schema: [],
},
/**
* @param { import('eslint').Rule.RuleContext } context
* @return { import('eslint').Rule.RuleListener }
*/
create: function (context) {
return {
ExportDefaultDeclaration: (node) => {
const hasSatisfies = node.declaration.type === 'TSSatisfiesExpression';
const isMeta = node.declaration?.typeAnnotation?.typeName?.name === 'Meta';
const isMetaWithParameter = Boolean(node.declaration?.typeAnnotation?.typeParameters);
if (!hasSatisfies || !isMeta || !isMetaWithParameter) {
context.report({
node: node.declaration.typeAnnotation ?? node.declaration,
messageId: "exportDefaultTypeCheck"
});
}
},
};
},
};
/**
* @fileoverview Stories exports should include type checking using `Story` or `StoryObj`
* @author Sergey Kozlov
*/
"use strict";
const validStoryNames = ['Story', 'StoryObj'];
const validStoryNamesString = validStoryNames.map(name => `\`${name}\``).join(' or ');
module.exports = {
/**
* @type { import('eslint').Rule.RuleMetaData }
*/
meta: {
type: "suggestion",
docs: {
description: `Stories exports should include type checking using ${validStoryNamesString}`,
recommended: false,
},
messages: {
exportStoryType: `stories \`export\` should be typed as ${validStoryNamesString}`,
},
schema: [],
},
/**
* @param { import('eslint').Rule.RuleContext } context
* @return { import('eslint').Rule.RuleListener }
*/
create: function (context) {
return {
ExportNamedDeclaration: (node) => {
const nodeStoryId = node.declaration.declarations[0].id;
if (nodeStoryId) {
if (validStoryNames.includes(nodeStoryId.typeAnnotation?.typeAnnotation?.typeName?.name)) {
return;
}
context.report({
node: nodeStoryId?.typeAnnotation ?? nodeStoryId,
messageId: "exportStoryType"
});
}
},
};
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment