/type-tests: TSTyche type tests (TDD step 3)
SkillDev toolsStep 3 of the Weft TDD workflow. Use after /mock: assesses whether the feature has meaningful type-level surface and, if so, writes __type-tests__/*.tst.ts TSTyche type tests with expect().type matchers. If not applicable, records an explicit skip in specs.md, never a silent skip.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the /type-tests: TSTyche type tests (TDD step 3) skill
What this skill tells your AI
The instructions your AI receives, as published by stefvw93/weft in .claude/skills/type-tests/SKILL.md and read by ahel’s review.
Verify the mocked type surface with TSTyche, or record an explicit, reasoned skip.
When to run
- Previous step:
/mock(thedeclare-based surface must exist in the source file). - Next step:
/unit-test. - Gate: the step always concludes with either a
.tst.tsfile or an explicittype-tests: not applicable, <reason>line inspecs.md. Silent skips are forbidden.
Procedure
-
Assess applicability. Does the feature have meaningful type-level behavior worth locking down?
- Generics and generic constraints
- Overloads
- Conditional/inferred types (what does the compiler deduce for a consumer?)
- Surfaces that must reject plausible-but-wrong usage
Trivial concrete signatures (already fully enforced by the main typecheck) do not warrant a type test.
-
If not applicable: add to the feature's
specs.md:type-tests: not applicable, <one-line reason>Report the skip and reason to the user, then hand off to
/unit-test. -
If applicable: write the test file at
src/**/__type-tests__/<feature>.tst.tsin the owning package (discovery is governed by roottstyche.jsontestFileMatch). Each file is self-contained and tests one feature. Pattern:import { expect, test } from "tstyche"; test("descriptive name of the behavior", () => { // Positive: exact type identity. expect(someValue).type.toBe<SomeType>(); // Pure type-level comparison (no value involved). expect<Derived<A>>().type.toBe<Expected>(); // Assignability when identity is not the intent. expect(wider).type.toBeAssignableTo<Narrow>(); // Negative: rejected call (argument types/arity). expect(fn).type.not.toBeCallableWith("bad", 123); // Negative: property must not exist. expect(obj).type.not.toHaveProperty("secret"); });Cover:
- Positive cases: valid usage compiles and inference lands on the expected types. Assert with
.type.toBe<T>()(exact identity; prefer overtoBeAssignableTounless assignability is the intent). - Negative cases: each rejection asserted by one
.notmatcher. Where no matcher fits (wrong-assignment-type, contextual typing inside a larger expression), keep a// @ts-expect-error <fragment>directive. TSTyche requires a fragment of the expected diagnostic message after the directive and validates it (checkSuppressedErrors). Put prose on its own comment line above. - One assertion per rejection. A single check swallowing two mistakes proves nothing.
Constraints:
declarefixtures live at module scope (declareis illegal insidetest()bodies).test()callbacks must not start comments with@ts-expect-errorunless they are real directives. TSTyche parses them. - Positive cases: valid usage compiles and inference lands on the expected types. Assert with
-
Validate with
vp run test:types(never baretstyche/vp test: the pack rule; dom/router/website tests resolve@weftui/*through builtdist/). The files also stay inside the tsc program (include: ["src"]), sovp run checkstill typechecks the test code itself. But onlyvp run test:typesevaluates the assertions; a failedtoBeis invisible tovp run check. -
Hand off. Next step is
/unit-test.
Rules
.tst.tsextension, under__type-tests__/, self-contained per feature.- Import test globals from
"tstyche"(expect,test); no hand-rolledExpect<Equal<>>helpers. - Type tests run against the mock surface. They must pass before implementation exists (they compare types, not runtime behavior).
- If writing the tests reveals the mocked types are wrong, apply the pause rule: go back to
/spec+/mockfirst. - TSTyche runs its own pinned TypeScript (
targetintstyche.json) because the workspacetypescript@7(tsgo) exposes no JS language-service API. On checker disagreement, trustvp run checkfor program correctness and TSTyche for assertion verdicts.
Signals
- GitHub stars
- 44
- Forks
- 1
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
type-tests- Source
- github.com/stefvw93/weft