From 799849cc41f00d93a82d63d79dfc3cf2ad98fc45 Mon Sep 17 00:00:00 2001 From: technicalcandidate-stack Date: Fri, 30 Jan 2026 11:43:16 -0800 Subject: [PATCH] fix: preserve literal types in Infer by using const type parameter - Change literal to literal for proper type inference - Add type-level tests to verify literal types are preserved - Add TypeScript 5.0+ requirement to README - Add optional peerDependency on TypeScript >=5.0.0 The const type parameter modifier (TS 5.0+) prevents type widening, so Infer now correctly produces 'text' instead of string. --- README.md | 7 +++++++ package.json | 8 ++++++++ src/predicates/literal.spec.ts | 13 +++++++++++++ src/predicates/literal.ts | 2 +- 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e3ee9c..90ff6ce 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,13 @@ runtyp is designed for speed. Here's how it compares to other popular programmat npm i runtyp ``` +## Requirements + +- **Node.js**: 18+ (or any modern browser) +- **TypeScript**: 5.0+ (for type inference features) + +> **Note**: JavaScript users can use runtyp without TypeScript. The TypeScript requirement only applies if you want type inference via `Infer<>`. + # Usage ## Example diff --git a/package.json b/package.json index 1069b30..9c51497 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,14 @@ "lint": "eslint ./ --ext .js,.ts", "build": "tsc" }, + "peerDependencies": { + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.59.2", "@typescript-eslint/parser": "^5.59.2", diff --git a/src/predicates/literal.spec.ts b/src/predicates/literal.spec.ts index 8f8a003..4e731e1 100644 --- a/src/predicates/literal.spec.ts +++ b/src/predicates/literal.spec.ts @@ -1,5 +1,18 @@ import {test} from 'kizu'; import {literal} from './literal'; +import type {Infer} from '..'; + +// Type-level test: Infer should preserve literal types +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const textValidator = literal('text'); + +type TextType = Infer; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-underscore-dangle +const typeTest: TextType = 'text'; +// @ts-expect-error - 'other' is not assignable to 'text' +// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-underscore-dangle +const typeTestFail: TextType = 'other'; test('literal(): valid inputs', (assert) => { diff --git a/src/predicates/literal.ts b/src/predicates/literal.ts index 7e88189..ff3d69d 100644 --- a/src/predicates/literal.ts +++ b/src/predicates/literal.ts @@ -1,6 +1,6 @@ import {Pred, ValidationResult} from '..'; -export function literal(expected: T): Pred { +export function literal(expected: T): Pred { return (value: unknown): ValidationResult => {