mirror of
https://github.com/sindresorhus/type-fest.git
synced 2026-01-25 14:57:30 +00:00
3.3 KiB
3.3 KiB
type-fest
TypeScript utility types library. Pure type-level programming—no runtime code.
Read .github/contributing.md for complete guidelines.
Commands
npm test # MUST pass before committing (runs all below)
npm run test:tsc # TypeScript compiler
npm run test:tsd # Type tests (tsd)
npm run test:xo # Linter
File Structure
source/type-name.d.ts → Type definition (.d.ts REQUIRED)
test-d/type-name.ts → Tests (tsd)
index.d.ts → Export (MUST add, lint enforces)
readme.md → API docs (add to category)
source/internal/ → Shared helpers (not exported)
Code Patterns
// ✅ CORRECT
import type {IsNever} from './is-never.d.ts'; // Include .d.ts
export type MyType<Value extends string> = ... // Descriptive names (not T/U)
export {}; // REQUIRED at end
// ❌ WRONG
import type {IsNever} from './is-never'; // Missing .d.ts
export type MyType<T> = ...; // Single-letter
/**
Creates a tuple type of specified length with elements of specified type.
Use-cases:
- Define fixed-length arrays with specific types
@example
import type {TupleOf} from 'type-fest'; type RGB = TupleOf<3, number>; //=> [number, number, number]
@category Array
*/
export type TupleOf<Length extends number, Fill = unknown> = ...;
export {};
Type params: Value, Target, Item, Length, Element, Key (not T, U, V, K)
Docs: No * prefix. First line → readme. Include use-cases, examples, @category.
Testing
ALWAYS test edge cases (any, never, unknown).
expectType<string>('' as MyType<'foo'>); // Basic
expectType<any>('' as MyType<any>); // any/never/unknown
expectNotAssignable<MyType<'foo'>>({wrong: true}); // Negative
expectError<MyType<number>>(); // Should error
Study: source/tuple-of.d.ts, is-equal.d.ts, literal-union.d.ts, internal/*.d.ts
Workflow
- Research - Study
source/similar types + online research - Define -
source/type-name.d.tswith docs - Test -
test-d/type-name.tswith edge cases - Export - Add to
index.d.ts+ readme.md - Verify -
npm testmust pass - Commit -
Add `TypeName` typeor`TypeName`: Fix description
Critical Rules
- Import paths MUST include
.d.tsextension - Files MUST end with
export {}; - Types MUST be exported from
index.d.ts - Type params MUST use descriptive names (not
T/U) - MUST test
any,never,unknownedge cases - First doc line MUST be concise (goes in readme)
- Use realistic examples with
//=>comments - Include
@categorytags - Fix lint issues, don't disable rules
Type Programming
- Conditionals:
T extends U ? X : Y - Recursion:
type Loop<T, Acc> = ... Loop<...> ... - Extract:
infer Item - Distribute:
T extends any ? ... : never - Count via tuple
['length'] - Union distribution is tricky—test it
Philosophy
- Correctness > cleverness
- Real problems only
- Docs teach how, not what
- Edge cases mandatory
- One concept per PR
- Descriptive names > brevity
- No unrelated changes
Troubleshooting
- Tests fail? Check
.d.tsimports,export {};, edge cases (any,never,unknown) - Lint errors? Add to
index.d.ts, fix issues (don't disable rules)