Skip to content

fix: compile existing type assertions in normal test commands (CORE-01) - #16

Draft
YLfjuk wants to merge 3 commits into
mainfrom
fix/core-01-type-assertion-discovery
Draft

YLfjuk wants to merge 3 commits into
mainfrom
fix/core-01-type-assertion-discovery

Conversation

@YLfjuk

@YLfjuk YLfjuk commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

Existing .spec.ts files ran as JavaScript, but their expectTypeOf assertions were not compiled: Vitest's default typecheck discovery selects declaration-style type tests, and each package tsconfig includes only src.

This change adds a no-emit test tsconfig per package and uses it for both test:types and explicit per-project Vitest typecheck discovery. Normal test, test:v, and coverage commands now compile the existing assertions in types, utils, and core. Source-only build configs remain unchanged. Vitest 4.1.11 invokes the TypeScript 7.0.2 CLI successfully once discovery and compiler input files are configured; no dependency or build-pipeline migration is needed.

UnionToTuple assertions check the complete member union and exact tuple length, plus empty/singleton cases. LastOfUnion assertions check that the result is a non-never member, is not a union of multiple disjoint literals, and preserves singleton/empty cases. Neither test assumes compiler-specific union ordering. No type implementations changed. The public UnionToTuple JSDoc correction belongs to CORE-04 in #17; clarifying LastOfUnion's compiler-dependent “last” wording is a separate documentation follow-up.

A small test:discovery guard runs before typechecking in CI. It creates an incorrect expectTypeOf<number>().toEqualTypeOf<string>() assertion in each existing test directory and requires both the package compiler command and root Vitest command to diagnose that exact file. It detects missing discovery even when another genuine test already fails.

The guard checks npm_execpath before creating fixtures and gives an actionable invocation error when it is missing. JavaScript CLI paths run through Node; native executables run directly without a shell. Cleanup attempts every owned fixture, reports filesystem errors, and exits unsuccessfully if any removal fails. Forced termination can leave invalid specs behind: three narrow Git ignore patterns prevent accidental staging of generated fixtures. No signal/process framework was added.

Validation on Windows, Node 24.19.0 / pnpm 11.22.0:

  • Pass: frozen-lockfile install; pnpm run fmt:check; pnpm run lint with 10 existing warnings; git diff --check.
  • Pass: pnpm run test:discovery. All three compiler commands reject the deliberate assertion with TS2344; root Vitest rejects all three with TypeCheckError. No generated sentinel files remain.
  • Pass: the full guard using the pinned pnpm 11.22.0 native Windows executable from the official @pnpm/exe distribution, downloaded only under ignored local artifacts. No global installation or configuration changed. Other native platforms were not tested. This is a portability fix, not a demonstrated current CI failure: pnpm/action-setup defaults standalone to false for pnpm 11.
  • Fault injection: removing the types test directory from compiler inputs, or disabling core Vitest typechecking, makes the guard fail. Both configurations were restored and fixtures were removed.
  • Fault injection: forcing the first unlink to fail still attempts all three removals, reports the cleanup error, and exits 1. The single remaining sentinel is ignored by Git and was then manually removed. Missing npm_execpath fails with the invocation guidance and leaves no fixtures.
  • Pass: types and core package test:types; source-only tsc -p tsconfig.json --noEmit in all three packages.
  • Pass: pnpm run build --force, all three tasks uncached, including types runtime/type tests, publint, and attw. Existing experimental/no-output/profile warnings remain.
  • Expected failure: utils test:types, root pnpm run test:types, root pnpm run test, and pnpm run coverage, due only to packages/utils/__tests__/enum/to-tuple.spec.ts:18, TS2344 / TypeCheckError. Coverage reports 129 passing file entries, one failed typecheck file, 657 passing tests, one failed assertion, and nine todo. Runtime and typecheck entries are both counted.

Blocked draft: CORE-04 in #17 must resolve Enum.toTuple/enumToTuple's false ordering contract before normal checks can pass honestly. Its assertion is unchanged. This PR does not remove that API, exclude tests, weaken real assertions, or add suppression directives. CORE-04 was not merged or rebased into this branch.

Earlier optional exact-property diagnostics remain outside this revision: PickOptional is CORE-09; PatchUnion expectations need coordination; the exact-mode matrix is CORE-18. The default compiler mode is preserved. CORE-02 audit work was not changed or re-audited.

Tooling/tests/docs only: no consumer-facing package change, version bump, or changeset. No review comments, merge, approval, publication, deployment, or watchers.

README-only follow-up: removed the discovery guard implementation and recovery paragraph at the reviewer's request. The development command list, test tsconfig explanation, and discovery guard behavior remain. pnpm run fmt:check and git diff --check pass for this follow-up; the full test suite was not rerun.

@changeset-bot

changeset-bot Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 528e5bb

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment thread README.md Outdated

Each package's `tsconfig.test.json` includes its source and existing `.spec.ts` tests. Both `test:types` and Vitest use it, so `test`, `test:v`, and `coverage` check type assertions too. The source-only `tsconfig.json` files remain separate for package builds.

`pnpm run test:discovery` temporarily adds an invalid `expectTypeOf` assertion to each package and verifies that both the package compiler command and root Vitest command report it. Its `finally` block attempts to remove every temporary file on success or a handled failure. Forced termination or filesystem errors can leave files behind. Before rerunning tests, manually delete any `*-typecheck-discovery-*.spec.ts` files in `packages/types/__tests__`, `packages/utils/__tests__`, and `packages/core/tests`. These generated files are ignored by Git.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nah, remove this

type Actual = LastOfUnion<Members>;

expectTypeOf<Actual>().toEqualTypeOf<Expected>();
// Union ordering is not guaranteed by TypeScript.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then this type is kind of useless

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant