eslint-plugin-storybook
eslint-plugin-storybook copied to clipboard
Type errors for stories args are not thrown when running lint
Describe the bug I've noticed some inconsistent behavior with the linting rules for stories, but it will be easier to explain with a simple example. Let's say we have a basic button component that looks like this:
type ButtonVariant = "primary" | "secondary";
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: ButtonVariant;
}
export const Button: React.FC<ButtonProps> = ({ ...props }) => {
return <button {...props}>click</button>;
};
and we wrote some simple stories for it:
type StoryProps = ComponentProps<typeof Button>;
const meta: Meta<StoryProps> = {
component: Button,
tags: ["autodocs"],
argTypes: {
variant: {
options: ["primary", "secondary"],
control: {
type: "select",
},
},
},
};
export default meta;
type Story = StoryObj<StoryProps>;
export const Primary: Story = {
args: {
variant: "variant-that-do-not-exist-or-whatever",
},
};
export const Secondary: Story = {
args: {
variant: "secondary",
},
};
when the file is opened in the editor, the linter highlights the "variant" property with an error message, but running the lint script doesn't result in an error.
To Reproduce Steps to reproduce the behavior:
- Provide any error value for one of args properties in Story object
- Save file
- Run lint
Expected behavior IMO error should be thrown by eslint. Or shouldn't be? If not, then why?
Screenshots
File:
Terminal output after running lint:
Additional context Below you can find rest of the project config.
package.json
{
"name": "playground",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.6.1",
"@eslint/js": "8.57.0",
"@storybook/addon-essentials": "8.2.4",
"@storybook/addon-interactions": "^8.2.9",
"@storybook/addon-links": "^8.2.9",
"@storybook/addon-onboarding": "^8.2.9",
"@storybook/blocks": "^8.2.9",
"@storybook/react": "8.2.4",
"@storybook/react-vite": "8.2.4",
"@storybook/test": "8.2.4",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "8.1.0",
"@typescript-eslint/parser": "8.1.0",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "8.57.0",
"eslint-plugin-react": "7.35.0",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-react-refresh": "0.4.7",
"eslint-plugin-storybook": "0.8.0",
"globals": "^15.9.0",
"storybook": "8.2.4",
"typescript": "^5.5.3",
"typescript-eslint": "^8.0.0",
"vite": "^5.4.0"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"module": "ESNext",
"allowJs": false,
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": ["src"]
}
.eslintrc.cjs
module.exports = {
root: true,
extends: [
"eslint:recommended",
"plugin:react-hooks/recommended",
"plugin:react/jsx-runtime",
"plugin:storybook/recommended",
"plugin:@typescript-eslint/recommended-type-checked",
],
plugins: [
"react",
"react-hooks",
"react-refresh",
"@typescript-eslint",
"storybook",
],
env: { browser: true, es2020: true },
ignorePatterns: [
"dist",
"storybook-static",
".eslintrc.cjs",
"vite.config.ts",
],
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
ecmaFeatures: { jsx: true },
},
settings: {
react: {
version: "detect",
},
},
};