Model a constraint once, then let TypeScript carry it through every Hraness project. @hraness/types is a declaration-only package that combines the public type-fest type surface, a readonly NonEmptyArray, and an opt-in strict ambient reset.
It ships no JavaScript and has no runtime entrypoint.
Pin the repository to its immutable v0.1.1 tag:
{
"dependencies": {
"@hraness/types": "github:hraness/types#v0.1.1"
}
}bun installThe local NonEmptyArray keeps the first item in the type, so code that requires at least one value does not need a runtime assertion after the value has already been proved.
import type {
JsonValue,
NonEmptyArray,
UnknownRecord,
} from "@hraness/types";
type Command = {
argv: NonEmptyArray<string>;
context: UnknownRecord;
};
const command = {
argv: ["inspect", "artifact.json"],
context: { cwd: "/work" },
} as const satisfies Command;
const receipt = {
command: command.argv[0],
arguments: [command.argv[1]],
} satisfies JsonValue;command.argv[0] is string, not string | undefined. An empty tuple fails at compile time:
const empty = [] as const;
// Type 'readonly []' is not assignable to NonEmptyArray<string>.
const argv: NonEmptyArray<string> = empty;| Import | What it provides | What it changes |
|---|---|---|
@hraness/types |
The public type-fest utility types plus NonEmptyArray<Value> |
Nothing at runtime |
@hraness/types/reset |
The strict ambient corrections from @total-typescript/ts-reset |
TypeScript's built-in declarations for the project that imports it |
Use the reset from one declaration file in a consuming project:
// src/reset.d.ts
import "@hraness/types/reset";The reset is deliberately separate. Importing the root entrypoint does not alter global declarations.
Types describe values after TypeScript has accepted them. They do not parse a network response, validate JSON, sanitize input, or make an unchecked cast safe. Start foreign runtime data as unknown, validate it in the consuming project, and apply these types to the validated result.
The package stays product-neutral and runtime-free:
- both public entrypoints resolve to
.d.tsfiles; sideEffectsisfalse;- the package contains no JavaScript runtime implementation;
- the release is tested as an installed archive under both Bundler and NodeNext module resolution.
The repository checks the declarations in place and from a clean packed consumer:
bun run typecheck
bun run test:package
bun test ./srcThe clean-consumer test installs the packed artifact, imports both entrypoints, and compiles the same public types with TypeScript 6.0.3 under Bundler and NodeNext resolution.
You can. This package gives Hraness projects one reviewed dependency boundary, adds the readonly non-empty invariant, and exposes the strict reset without making either addition a runtime dependency.
No. Validate unknown data first. NonEmptyArray<Value> preserves an invariant that code has already established.
It affects the TypeScript program that includes the declaration file. Keep the import in the specific project that wants the stricter built-in declarations.
The packed public artifact is tested under Bundler and NodeNext. The repository's current compatibility witness uses TypeScript 6.0.3.
Read CONTRIBUTING.md before proposing a shared type. Add a deterministic compile-time witness for every exported invariant and run the complete package check before opening a pull request.
Report suspected vulnerabilities privately as described in SECURITY.md.
MIT