Skip to content

Kind-scoped tag types: per-kind tag tuple types from kind schema constraints #10

Description

@alltheseas

Problem

Tag letters are reused across NIPs with different semantics. Today codegen generates one generic type per tag letter:

type NTag = readonly ["n", "mainnet" | "testnet" | "signet" | "regtest"];

But NIP-66 uses n for "clearnet" | "tor" | "i2p" | "loki". A developer building a kind 30166 event gets the wrong autocomplete and wrong documentation from the generic NTag type.

Similarly:

  • c = commitment (generic) vs. check type in NIP-66 (open, read, write, ssl, dns, geo, info)
  • s = status (generic) vs. software name in NIP-66

Proposal

Generate tag types scoped to each kind, derived from the kind schema's tag constraints:

// Generic (existing, keep as-is)
export type NTag = readonly ["n", "mainnet" | "testnet" | "signet" | "regtest"];

// Kind-scoped (new)
export type Kind30166_NTag = readonly ["n", "clearnet" | "tor" | "i2p" | "loki"];
export type Kind30166_RTag = readonly ["R", `${"!" | ""}${"auth" | "payment" | "pow" | "ssl"}`];
export type Kind10166_CTag = readonly ["c", "open" | "read" | "write" | "ssl" | "dns" | "geo" | "info"];

Where the data comes from

The kind schemas already contain per-tag value constraints via if/then on tag position 0 and enum/pattern on subsequent positions. schemata PR #106 adds these for NIP-66 kinds. The codegen planner (plan-validators.ts) already extracts this info to generate validators — the same data can drive kind-scoped type emission.

Scope

  • New emitter logic (or extension of emit-typescript.ts) that walks kind tag constraints
  • Output: additional type aliases in kinds.d.ts or a new kind-tags.d.ts
  • Keep generic tag types in tags.d.ts unchanged (they're still useful for cross-kind tag handling)

Effort: Medium | Impact: Medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions