搜索

PythonReactSEOPDF
GitHub Skill

type-safety

Fix type assertions and improve TypeScript type safety. Use when encountering 'as unknown as' casts, manual type definitions that duplicate schema types, or unclear type errors in database queries, especially with Drizzle ORM relations. Also use when verifying types

wodsmith☆ 1 仓库 Stars1 仓库 Forks

安装与使用

请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。

查看来源 ↗使用指南

技能说明

Type Safety

Improve TypeScript type safety by eliminating unsafe type assertions and using proper types from the source.

CRITICAL: Drizzle Relation Type Inference Failure

This is a recurring bug in WODsmith. Drizzle's with: { relation: true } clause does NOT automatically include relation types in the return type. This causes:

error TS2339: Property 'workout' does not exist on type '{ id: string; trackId: string; ... }'
error TS2551: Property 'track' does not exist on type '{ ... }'. Did you mean 'trackId'?
Root Cause
  1. Query uses db.query.table.findFirst({ with: { workout: true } })
  2. Runtime: Returns object with workout property populated
  3. Compile time: TypeScript only sees base table columns, not relations
  4. Result: Type errors when accessing .workout, .track, .competition, etc.
Three Fix Strategies (Choose Based on Context)
Strategy 1: Type Alias with Cast (Simple, for single file use)
import { type TrackWorkout, type Workout } from "@/db/schema"

type TrackWorkoutWithWorkout = TrackWorkout & { workout: Workout }

const result = await db.query.trackWorkoutsTable.findFirst({
  where: eq(trackWorkoutsTable.id, id),
  with: { workout: true }
}) as TrackWorkoutWithWorkout | undefined
Strategy 2: Explicit Join (Most Type-Safe, for complex queries)

When relation chains are deep or you need specific fields:

// Instead of .with() which has type inference issues:
const result = await db
  .select({
    id: trackWorkoutsTable.id,
    trackId: trackWorkoutsTable.trackId,
    // ... other trackWorkout fields
    workout: workoutsTable,  // Full workout object
    // OR select specific fields:
    workoutName: workoutsTable.name,
    workoutScheme: workoutsTable.scheme,
  })
  .from(trackWorkoutsTable)
  .innerJoin(workoutsTable, eq(trackWorkoutsTable.workoutId, workoutsTable.id))
  .where(eq(trackWorkoutsTable.id, id))
Strategy 3: Type Guard for Optional Relations
// When relation might not be loaded
if (result && 'workout' in result && result.workout) {
  const workout = result.workout as Workout
  // Use workout safely
}

// Or with type guard function
function hasWorkout(tw: TrackWorkout): tw is TrackWorkout & { workout: Workout } {
  return 'workout' in tw && tw.workout !== undefined
}

Common WODsmith Type Error Patterns

Pattern 1: Missing .workout on trackWorkout

Error: Property 'workout' does not exist on type '{ createdAt: Date; ... workoutId: string; }'

Files affected: competition-scores.ts, competition-workouts.ts, programming.ts

Fix: Use Strategy 1 or 2 above.

Pattern 2: Missing .track or .competition

Error: Property 'track' does not exist... Did you mean 'trackId'?

Fix: Same strategies. The relation IS loaded, TypeScript just doesn't know.

Pattern 3: Missing New Schema Columns

Error: Property 'minHeatBuffer' is missing in type

Cause: Schema changed, new columns added, but code constructing objects manually doesn't include them.

Fix: Add the missing properties with appropriate defaults (usually null):

const tempWorkout = {
  ...existingFields,
  defaultHeatsCount: null,
  defaultLaneShiftPattern: null,
  minHeatBuffer: null,  // New field!
}
Pattern 4: Possibly Undefined Array Access

Error: 'rot1' is possibly 'undefined'

Fix: Add null checks before accessing:

// Bad
const rot1 = rotations.find(r => r.id === id1)
const rot2 = rotations.find(r => r.id === id2)
console.log(rot1.startingHeat)  // Error!

// Good
if (!rot1 || !rot2) {
  continue  // or throw, or return early
}
console.log(rot1.startingHeat)  // Safe

Prevention Checklist

When writing queries with relations:

  1. Check if return type includes relation properties
  2. If not, create type alias: type XWithY = X & { y: Y }
  3. Apply cast at query site: as XWithY | undefined
  4. For complex joins, prefer explicit .select().from().innerJoin()
  5. When constructing objects manually, check schema for ALL current columns

References

For detailed examples and patterns, see:

使用示例

查看来源仓库中的使用示例与配置说明。

查看来源 ↗

来源历史

收录时间
2026-01-20
索引更新时间
2026-02-03
Branch
main

收录与同步日期属于本站记录。源码修改历史请查看来源仓库。

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!