Agent skill
typescript-unknown-jsx-expression
Fix TypeScript error "Type 'unknown' is not assignable to type ReactNode" when using Record<string, unknown> values directly in JSX && short-circuit expressions. Use when: (1) JSX expression {someObj.field && <Component />} fails with TS2322, (2) Reading from a JSON or untyped object via bracket notation in JSX conditionals, (3) Values typed as unknown appear in JSX even when wrapped in String() or guarded with truthiness checks. Fix: use !! to coerce to boolean before the && operator.
Install this agent skill to your Project
npx add-skill https://github.com/yorch/claude-skills/tree/main/typescript-unknown-jsx-expression
SKILL.md
TypeScript unknown in JSX && Expressions
Problem
When using Record<string, unknown> (or any unknown-typed values) in JSX conditional
rendering with &&, TypeScript raises:
Type 'unknown' is not assignable to type 'string | number | bigint | boolean |
ReactElement<...> | Iterable<ReactNode> | ReactPortal | Promise<...> | null | undefined'
Even when the value is wrapped in String(), the error still occurs because the
JSX expression itself evaluates to unknown | JSX.Element.
Context / Trigger Conditions
- Object is typed as
Record<string, unknown>(common with JSON fields from APIs) - JSX contains:
{obj.field && <Component value={String(obj.field)} />} - Error TS2322 on the
&&line, not inside the Component - TypeScript strict mode enabled
Root Cause
In TypeScript, a && b returns the type of a when a is falsy — so unknown && JSX.Element
resolves to unknown | JSX.Element. TypeScript cannot prove unknown is a valid ReactNode,
so it rejects the expression.
Solution
Force a boolean result with !! before the &&:
// ❌ FAILS — wd.entry_time is unknown
{wd.entry_time && (
<DetailField value={String(wd.entry_time)} />
)}
// ✅ WORKS — !!wd.entry_time is boolean
{!!wd.entry_time && (
<DetailField value={String(wd.entry_time)} />
)}
// Also works with null check
{wd.entry_time != null && (
<DetailField value={String(wd.entry_time)} />
)}
For chained &&:
// ❌ FAILS — first && returns unknown
{wd.needs_reentry && wd.reentry_date && (
<DetailField value={String(wd.reentry_date)} />
)}
// ✅ WORKS — both forced to boolean
{!!wd.needs_reentry && !!wd.reentry_date && (
<DetailField value={String(wd.reentry_date)} />
)}
Verification
yarn frontend:typecheck # or tsc --noEmit
# Should produce no TS2322 errors on the affected lines
Notes
- This is not a React issue — it's a TypeScript type-narrowing limitation with
unknown String(unknown)returnsstring(which is valid ReactNode), but the issue is the JSX expression type beforeString()is applied- Alternative: cast the whole object with a more specific type at the call site
const wd = (r.workDetails ?? {}) as Record<string, string | boolean | undefined>— this eliminates all!!guards but reduces type safety !!is the idiomatic JS/TS way to coerce any value to boolean
References
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
gha-docker-publish
ALWAYS invoke this skill before writing any GitHub Actions workflow that builds or pushes Docker images — it contains specific opinionated patterns that produce secure, reliable workflows and that you cannot reliably guess. The conventions it enforces include: (1) datetime+SHA image tags in YYYYMMDDHHMMSS_sha format for unambiguous build traceability, (2) a `workflow_dispatch` boolean `push` input that defaults to `false` (safe dry-run by default — a common mistake is using `type:choice` with `dry_run` inversion instead), (3) a `publish-docker` PR label gate that lets CI validate builds on PRs without pushing, (4) conditional `latest` tag using `enable={{is_default_branch}}` (never hardcoded `enable=true`), (5) GHA layer cache with `mode=max` for maximum rebuild speed, (6) no inline `${{ github.sha }}` in `run:` scripts (security hardening), (7) dual-registry login and push patterns when publishing to both GHCR and a private registry. Use this whenever the user asks to: set up GHCR publishing, add a docker-publish.yml workflow, add layer caching to Docker CI, configure datetime/SHA image tags, add a manual build-only dispatch trigger, push to multiple registries, or build Docker images on PRs.
prisma-7-docker-migrations
Run Prisma 7 migrations inside a multi-stage Docker production image. Use when: (1) `prisma migrate deploy` crashes with "Cannot resolve environment variable: DATABASE_URL" or "cannot find module" at container startup, (2) building a production Docker image that needs to run migrations before starting the server, (3) you copied only node_modules/prisma + node_modules/@prisma but the Prisma 7 CLI still fails with MODULE_NOT_FOUND at runtime, (4) Yarn 4 node-modules linker .bin/prisma symlink breaks after Docker COPY. Covers prisma.config.ts (Prisma 7), full node_modules copy requirement, and symlink recreation pattern.
code-changes-review
Perform a comprehensive code review of current uncommitted changes in a git repository. Analyzes for bugs, security vulnerabilities, best practices, DRY violations, code smells, performance issues, and areas of improvement. Use when: review changes, code review, check my code, review diff, pre-commit review, PR review, quality check. Works with any language or framework.
rails-auto-assigned-field-validation
Fix for Rails models where validates :field, presence: true causes ALL creates to fail when the field is set by a before_create callback. Use when: (1) validates :number, presence: true is added to a model that uses before_create to auto-assign a sequence number, (2) model creates silently fail with "number can't be blank", (3) auto-generated fields (number, slug, token) fail presence validation despite being set in callbacks. Root cause: before_create runs AFTER validations. Fix: change before_create to before_validation on: :create.
app-docker-deploy-with-traefik
Generate Docker and Traefik deployment configurations for any application (Node.js, Python, Go, Rust, Java). Creates Dockerfile, docker-compose.yml, docker-compose.for-traefik.yml overlay, and .env.sample with production best practices. Use when: dockerize app, containerize, add Docker, deploy with Traefik, reverse proxy setup, HTTPS/SSL, Let's Encrypt certificates, production deployment, docker-compose setup. Requires: Docker, docker-compose.
edit-article
Edit and improve articles by restructuring sections, improving clarity, and tightening prose. Use when user wants to edit, revise, or improve an article draft.
Didn't find tool you were looking for?