Skip to content

Latest commit

Β 

History

History
100 lines (66 loc) Β· 2.58 KB

CONTRIBUTE.md

File metadata and controls

100 lines (66 loc) Β· 2.58 KB

😺 Contributing to is-kit

πŸŽ‰ Thanks for considering contributing to is-kit!

We welcome any improvements, whether it's a feature, bugfix, test, or documentation change.


πŸ›  Setup

pnpm install

To run tests locally:

pnpm test && pnpm test:types

Optional checks:

pnpm lint
pnpm build

Workflow

  1. Fork this repository
  2. Clone your forked repository
git clone https://github.com/nyaomaru/is-kit.git
cd is-kit
  1. Create a feature branch
git checkout -b your-feature-name

🌱 Branch Naming Convention

We don't enforce strict rules on branch naming.

But we recommend using descriptive names for clarity.

Feel free to set your naming like below.

Examples:

  • feat/add-new-combinator
  • fix/not-refinement-edge-case
  • docs/update-readme

πŸ’¬ Commit Message Style

Follow Conventional Commits:

(Don't worry if you forget itβ€”happens to the best of us!)

type(scope): brief description

e.g.,
feat(combinators): add oneOfValues fast path
fix(logic): correct not() exclusion typing

Types include: feat, fix, docs, refactor, test, chore

πŸš€ Pull Request Process

  • Make sure all checks pass: pnpm lint, pnpm build, pnpm test, pnpm test:types
  • Describe what you changed and why
  • If your PR resolves an issue, mention it (Closes #123)
  • Add or update tests (runtime and/or type tests) if applicable
  • Keep PRs focused and concise
  • Feel free to open it as a Draft PR while you're still working.

πŸ“ Style Guide

  • No strict rules
  • Keep the code clean, readable, and documented
  • Prefer descriptive naming
  • Add JSDoc comments when introducing new public functions

TypeScript guard/refinement conventions

  • Prefer returning Predicate<T> for guards that accept unknown and narrow to T.
  • Use Refine<A, B> when the input type is already known (A) and you refine to a subtype (B).
  • Keep overloads that accept a typed input (e.g. oneOf<A>(...) : (input: A) => input is ...) as-is; Predicate<...> is only for the unknown-input shape.
  • For comparator-style helpers, use const generics to preserve literal types (e.g., equals<const T>(target: T): Predicate<T>), enabling precise narrowing to the exact literal.
  • When a returned function must carry additional generics on the input (e.g., equalsKey returning <A>(input) is A & ...), keep the type predicate form; do not force Predicate<...> at the cost of expressiveness.

Thank you again! πŸ™Œ

If you have any questions or ideas, feel free to open a discussion or issue. πŸš€