Claude Code Plugins

Community-maintained marketplace

Feedback
3
0

Branded types, Effect Schema, type-first development

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name type-safety
description Branded types, Effect Schema, type-first development
allowed-tools Read, Write, Edit, Grep
token-budget 400

type-safety

Branded Types

Prevent mixing incompatible values at compile time:

import { Brand } from "effect";

type UserId = string & Brand.Brand<"UserId">;
type OrderId = string & Brand.Brand<"OrderId">;

const UserId = Brand.nominal<UserId>();
const OrderId = Brand.nominal<OrderId>();

const userId = UserId("user-123");
const orderId = OrderId("order-456");

// Compile error: Type 'OrderId' is not assignable to type 'UserId'
getUser(orderId);

TypeScript Types as SSOT

Define types FIRST, then create schemas that satisfy them:

import { Schema } from "effect";

// 1. Type is source of truth
type User = {
  readonly id: UserId;
  readonly name: string;
  readonly email: string;
};

// 2. Schema satisfies the type
const UserSchema = Schema.Struct({
  id: Schema.String.pipe(Schema.brand("UserId")),
  name: Schema.String,
  email: Schema.String.pipe(Schema.pattern(/@/)),
}) satisfies Schema.Schema<User, unknown>;

NEVER use typeof Schema.Type - that inverts the relationship.

Parse at Boundaries

// API boundary - parse incoming data
const handler = Effect.gen(function* () {
  const raw = yield* readRequestBody();
  const user = yield* Schema.decodeUnknown(UserSchema)(raw);
  // user is now fully typed
  return yield* saveUser(user);
});

Internal code trusts the types - no runtime checks needed.

Anti-Patterns

  • any → Use unknown + type guards
  • z.infer → TypeScript type is SSOT
  • Plain string IDs → Use branded types
  • Runtime checks everywhere → Parse at boundary only