跳到正文
cccskills
免费在 GitHub 公开中文介绍

narrow-react-prop-types

按应用中的真实调用方式收紧 React 组件的属性类型,清理无用的可选项、备用值和条件分支,并调整测试与 Storybook 示例以符合新类型。

原文查看原文说明

narrow React component prop types to match live code paths

humanlayer/humanlayer星标 12,707(GitHub 12,707 + cccskills 0)

实测评分 未实测

查看安装方法

适用场景

  • 检查哪些属性确实可以省略
  • 要求始终显示的按钮提供处理函数
  • 清理不再需要的备用逻辑
  • 让测试和 Storybook 符合实际调用

中文介绍

功能

此技能会根据应用中的实际用法检查 React 组件属性。它会查找真实调用位置,并将属性分为必填、可选或未使用,再收紧公开类型、移除无用属性和仅用于应对不真实状态的备用分支。若子组件或多个派生组件共用宽松类型,也可以一并调整。测试和 Storybook 示例则改为提供符合真实用法的值与处理函数。

适用场景

当属性类型为了 Storybook、模拟数据、测试或演示而放宽,导致组件能够表达应用实际不会出现的状态时,可以使用此技能。例如,按钮始终显示时,可将其处理函数设为必填;也可以清除真实调用方不需要的备用值和条件判断。它也适用于检查共用同一属性类型的派生组件。

使用示例

  • “检查这个组件在应用中的真实调用位置,并收紧属性类型。”
  • “调整 Storybook 和测试,让它们提供必需的处理函数。”

注意事项

属性契约以非测试、非 Storybook 的真实调用位置为依据。属性必须传入但值可以为 null,与属性本身可以省略是两种情况。修改后,应检查改动包以及使用该组件的应用或包的类型。

本介绍由 AI(OpenAI Codex)根据公开的 SKILL.md 撰写。准确的规格请查看下方原文。

文档检查

AI 根据 SKILL.md 的内容检查了需要注意的操作和使用前提。评分只依据实际运行的结果(实测对比)。

安全性发送数据、删除文件、执行命令等是否有说明
A良好内容集中于代码和类型调整,未说明外部发送、删除或读取凭据。
安装难易度所需工具和 API 密钥是否少且有说明
A良好未要求 API 密钥或付费服务;验证方式是运行仓库类型检查。

不计入评分。 由 AI(OpenAI Codex)于 2026年10月29日 评估。仅供参考,安装前请同时查看原文。

如果您认为评估有误,请申请复核

请写明哪一项有误以及原因。无需登录。我们会对照 SKILL.md 重新评估,并在此处更新结果。

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

包含的文件(1)

  • SKILL.md6.9 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Narrow React Prop Types

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.

Core Requirements

  • Find the actual non-test, non-Storybook call sites before changing types.
  • Treat live code paths as the source of truth for the prop contract.
  • Do not preserve optional props only because they make Storybook, tests, or mock data easier.
  • Keep props optional only when there are non-Storybook, non-test call sites which do not provide them and which have a good reason for not doing so.
  • Types should not enable expressing states which are not observed in non-test, non-Storybook call sites.
  • Types should be as strict as possible so code can be as simple as possible.
  • Prefer deriving and extracting types from existing live-code-path values and APIs where possible.

Workflow

1. Identify the suspect component

Look for components with these signals:

  • Large props interfaces with many optional fields.
  • Optional callback calls such as onSelect?.(...) or onArchive?.(...).
  • Fallback state handling such as items ?? [], count ?? 0, or handler && ... around values live code likely always supplies.
  • UI affordances that always render even though their callbacks are optional.
  • Props that look demo-oriented, such as 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.

2. Find every live usage

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:

  • Live code paths: app routes, wired components, providers, hooks, production package exports, and shared components used by those paths.
  • Support code: Storybook stories, test files, fixtures, mocks, demo harnesses, and visual-only examples.

Only live code paths should determine what the component API supports.

3. Derive the real types from the live code paths

Read the live call sites and classify each prop:

  • Required: every non-test, non-Storybook call site supplies it.
  • Optional: at least one non-test, non-Storybook call site omits it and that omission is a meaningful runtime state.
  • Removed: no non-test, non-Storybook call site uses it.

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.

4. Tighten the public prop type

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?.(...).

5. Derive and extract types where possible

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.

6. Tighten internal child props too

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)

7. Remove fallback logic for unsupported states

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

8. Update all variants that share the prop type

If multiple components share the broad prop type, update them together so they all enforce the same live-code-path contract.

9. Let tests and stories adapt to live code

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.

10. Validate the change

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>

Review Checklist

  • The changed prop type was derived from non-test, non-Storybook call sites.
  • Optional callbacks are removed for always-rendered interactions.
  • Rendered menu items and buttons cannot be inert because of missing handlers.
  • Removed props are not used by live code paths.
  • Nullability is preserved only for real states, such as no current focus.
  • Types are derived or extracted where possible rather than manually duplicated.
  • useState<T>(...) is used where inference would otherwise widen or obscure the intended state.
  • Shared variants compile against the same narrowed contract.
  • Typecheck passes for the shared package and consuming live app/package.

Anti-Patterns to Avoid

  • Making callbacks optional so stories can omit them.
  • Rendering a menu item that calls onAction?.(...).
  • Adding default* props for Storybook when live code is controlled.
  • Using ?? [] or ?? 0 to hide missing required live state.
  • Accepting multiple API shapes when live code only uses one.
  • Treating pure components as mock components with relaxed contracts.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Automate website navigation, form entry, and clicks through a browser command line tool. Extract page text, capture screenshots, and compare page states to check interactions or test web app behavior across screen sizes.

中文简介正在准备中。当前显示英语简介。

  • Automate form entry and button clicks
  • Extract text from web pages
  • Save page screenshots and PDFs
humanlayer/humanlayer1.3万2026年10月29日 更新

asd-ste100

免费有简介

依据 ASD-STE100 的原则,将含糊或冗长的英文改写为简短、直接的句子。保留事实和条件,指出问题与修改理由,并用表格对照原文和改写内容。

  • 明确给其他智能体的英文指令
  • 简化英文工具说明或错误信息
  • 整理给非英语母语者阅读的内容
humanlayer/humanlayer1.3万2026年10月29日 更新

better-github-skill

免费有简介

通过专用脚本查看 GitHub 拉取请求状态、评审对话和 CI 失败信息。汇总检查结果与未解决的讨论,并查看失败任务或步骤的日志片段;完整日志会保存到文件。

  • 汇总拉取请求状态
  • 查看未解决的评审对话
  • 调查失败的 CI 任务和步骤
humanlayer/humanlayer1.3万2026年10月29日 更新

bump-version

免费有简介

为支持的程序包更新发布基准版本,同步相关文件中的版本字段并核验生成结果;流程还包括提交、推送,以及合并后的发布说明。

  • 提高发布用的程序包基准版本
  • 同步多个文件中的版本字段
  • 推送前核验生成版本
humanlayer/humanlayer1.3万2026年10月29日 更新

calldiff

免费有简介

比较Git提交、分支或工作区代码中的函数调用结构,可查看调用树、追踪函数间的调用路径,并支持22种语言。

  • 比较代码修改前后的调用关系
  • 审查不同分支的调用结构
  • 追踪两个函数之间的调用路径
humanlayer/humanlayer1.3万2026年10月29日 更新

chrome-devtools-cli

免费有简介

通过 `chrome-devtools-mcp` CLI 在终端自动操作浏览器,包括查看页面元素、点击和填写表单、切换标签页及截图,还可检查网络请求、控制台消息、性能和内存。

  • 自动填写表单并跳转页面
  • 截取页面或元素图像
  • 检查网络请求和控制台错误
humanlayer/humanlayer1.3万2026年10月29日 更新

查看 humanlayer 的全部技能

报告此技能的问题