一键导入
narrow-react-prop-types
narrow React component prop types to match live code paths
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
narrow React component prop types to match live code paths
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | narrow-react-prop-types |
| description | narrow React component prop types to match live code paths |
Use this skill when a React component's props have been widened for stories, mocks, tests, or demos and now express states the live application does not enter.
The goal is to make component types describe the real live-code-path contract, then require stories/tests/mocks to adapt to that contract instead of weakening it.
For an example recurring GitHub Actions workflow that runs this skill through CodeLayer, see references/agent-narrow-component-props.yml. Its example agent memory file is references/narrow-component-props-memory.md. For CI agent response formatting, see references/response-template.md.
Look for components with these signals:
onSelect?.(...) or onArchive?.(...).items ?? [], count ?? 0, or handler && ... around values live code likely always supplies.defaultFoo, alternate handler shapes, or display toggles not used by live code.Do not pick a target from a story or test alone. Use stories/tests only as supporting evidence that the type has been widened, not as evidence that a state is real.
Search for all imports/usages of the component, exported prop type, and shared child primitives.
Classify call sites by whether they are live code paths or support code:
Only live code paths should determine what the component API supports.
Read the live call sites and classify each prop:
Nullability and optionality are different. If live code always passes a prop but the value can be empty, prefer a required nullable prop such as focusedItem: FocusedItem | null over focusedItem?: FocusedItem | null.
Update exported prop types to match only the states observed in live code paths.
The looser and more optional a type is, the more possible states the component has to reason about. Every optional prop creates another branch the component must handle, test, and keep correct. Prefer strict types that prevent impossible states instead of broad types that require defensive render logic.
If the component always renders an interactive affordance, require the handler that makes it work. Do not allow inert states like a visible menu item that calls onRename?.(...).
Prefer deriving types from the live APIs instead of restating them manually:
Parameters<typeof fn>[0] for function argument types.ReturnType<typeof fn> for return types.Extract<Union, Shape> for narrowing a union to a real variant.React.Dispatch<React.SetStateAction<T>> for React state setters instead of approximating them as (value: T) => void.Prefer explicit state type parameters when inference would widen or obscure the intended state shape:
const [dialogState, setDialogState] = useState<DialogState>({
id: null,
isOpen: false,
})
Avoid relying on implicit useState(...) inference when it produces broad nullable object shapes, string literal widening, or callback types that later need hand-written approximations.
Do not stop at the exported component if it passes broad props into child primitives.
If row/menu/button child components receive optional handlers only because the parent props were broad, tighten those internal props too. Replace optional calls like this:
onRename?.(id, name)
with required calls:
onRename(id, name)
Once props are required, remove defensive fallbacks that only existed for widened types.
Examples:
new Set(expandedIds ?? defaultExpandedIds ?? [])
should become:
new Set(expandedIds)
items && items.length > 0
should become:
items.length > 0
If multiple components share the broad prop type, update them together so they all enforce the same live-code-path contract.
If a story or test breaks after narrowing props, fix it by providing realistic handlers and state. Do not make live-code-path props optional again to reduce test setup.
If the story/test setup feels verbose, create a test helper or fixture that satisfies the strict live-code-path contract. Keep the helper in support code; do not weaken the component API.
Run package-level typechecks for the changed package and each live app/package that consumes the changed component.
Use repository-specific validation commands when available. In this monorepo, prefer:
bun --bun run typecheck --filter <package>
When running as a CI agent, format your final response according to references/response-template.md. This response becomes the PR body.
Include:
useState<T>(...) is used where inference would otherwise widen or obscure the intended state.onAction?.(...).default* props for Storybook when live code is controlled.?? [] or ?? 0 to hide missing required live state.interview the user to design an agentic control loop (sensor, controller, actuator under disturbances) tailored to their codebase, then build it as locally-runnable components plus a scheduled coding-agent workflow
build a repo-local skill and install a matching iterated coding-agent GitHub Actions workflow, prompt, memory file, and reference templates
improve a CLAUDE.md file using <important if> blocks to improve instruction adherence