Fix "Return types are not inferred in standard mode"#758
Conversation
…and `arkenvVitePlugin` by leveraging `StandardSchemaV1` instead of ArkType.
🦋 Changeset detectedLatest commit: acbed78 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughImplements Standard Mode type inference for createEnv by adding a dedicated overload for Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Add new overload for standard schemas - Explicitly type arktype validator config - Remove ambiguous general overload
commit: |
📦 Bundle Size Report
✅ All size limits passed! |
- Update createEnv return cast for standard mode - Add comprehensive tests for standard mode inference - Ensure correct type inference for various schemas
- Mark validation tasks as complete - Refine type assertions in standard mode tests - Update test type error suppression
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@openspec/changes/fix-standard-mode-inference/specs/inference/spec.md`:
- Line 11: Fix the capitalization in the assertion sentence by changing the word
"Have" to lowercase "have" in the sentence "**THEN** the returned object MUST
Have types exactly matching the Zod output types" so it reads "**THEN** the
returned object MUST have types exactly matching the Zod output types"; update
that exact line in the spec (the sentence containing "MUST Have") to maintain
grammatical consistency.
🧹 Nitpick comments (7)
openspec/changes/fix-standard-mode-inference/specs/inference/spec.md (1)
14-16: Add missing GIVEN clause for consistency with scenario format.The second scenario lacks a GIVEN clause, which breaks the pattern established by the first scenario and the coding guidelines that specify using WHEN and THEN bullet points. Consider adding a GIVEN clause for completeness.
Suggested improvement
#### Scenario: Inferred types are usable without ArkType +- **GIVEN** a user consuming ArkEnv with Standard Schema validators - **GIVEN** `validator: "standard"` is used -- **THEN** types of the returned environment object MUST NOT depend on ArkType types at the consumer level +- **WHEN** the environment object is accessed +- **THEN** its types MUST NOT depend on ArkType types at the consumer levelopenspec/changes/fix-standard-mode-inference/design.md (1)
61-61: Minor: Hyphenate "ArkType-based" for grammatical correctness.Per standard grammar conventions, compound adjectives before a noun should be hyphenated.
Suggested fix
-Actually, the user said: "it obviously happens because the return types of createEnv are all arktype based, but in recent changes we've made it so that arktype is not required anymore." +Actually, the user said: "it obviously happens because the return types of createEnv are all ArkType-based, but in recent changes we've made it so that arktype is not required anymore."openspec/changes/fix-standard-mode-inference/proposal.md (1)
19-30: Add Impact section per coding guidelines.The proposal template should include an Impact section. Even if the impact is minimal (since this is primarily a type-level fix with no runtime changes), it's good to document this explicitly.
Suggested addition
## Explicit Non-Goals - Changing the runtime validation logic (already implemented). - Introducing complex auto-detection of schemas (we stick to the explicit `validator` flag). + +## Impact +- **Type-level only**: This change affects TypeScript inference but does not modify runtime behavior. +- **Non-breaking**: Existing code using ArkType mode (default) continues to work unchanged. +- **Standard mode users**: Will now get correct type inference matching their validator's output types (e.g., Zod, Valibot). ## Design PrincipleAs per coding guidelines, proposal.md files should include an Impact section.
packages/arkenv/src/standard-mode.test.ts (2)
14-40: Consider usingafterEachfor environment cleanup.Currently,
vi.unstubAllEnvs()is called at the end of each test. If a test fails or throws before reaching the cleanup line, the stubbed environment may leak into subsequent tests. Moving cleanup toafterEachensures consistent cleanup regardless of test outcome.Suggested refactor
describe("Standard Mode Type Inference", () => { + afterEach(() => { + vi.unstubAllEnvs(); + }); + it("should infer correct types from Standard Schema validators", () => { vi.stubEnv("STRING_VAR", "test"); vi.stubEnv("NUMBER_VAR", "42"); vi.stubEnv("BOOLEAN_VAR", "true"); // ... test body ... - vi.unstubAllEnvs(); });Apply the same pattern to all tests in the file.
As per coding guidelines: "Use beforeEach/afterEach for cleanup, not beforeAll/afterAll when possible."
102-123: Consider adding runtime value assertions for completeness.This test validates type-level correctness but doesn't assert the runtime values. While the type assertions are the primary goal, adding runtime assertions would make the test more comprehensive.
Suggested addition
expectTypeOf(env).toEqualTypeOf<{ VAR1: string; VAR2: number; VAR3: { nested: string }; }>(); + // Runtime assertions + expect(env.VAR1).toBe("string-output"); + expect(env.VAR2).toBe(999); + expect(env.VAR3).toEqual({ nested: "object" }); + vi.unstubAllEnvs(); });packages/arkenv/src/create-env.ts (2)
92-95: Consider narrowing standard-mode config to prevent unsupported options.Standard mode ignores
coerceandarrayFormat, butArkEnvConfigstill allows them (and defaultscoerceto true). A dedicated config type avoids misleading call sites.♻️ Suggested type tightening
+type StandardModeConfig = Omit<ArkEnvConfig, "coerce" | "arrayFormat" | "validator"> & { + validator: "standard"; + coerce?: false; + arrayFormat?: never; +}; + export function createEnv<const T extends Record<string, StandardSchemaV1>>( def: T, - config: ArkEnvConfig & { validator: "standard" }, + config: StandardModeConfig, ): { [K in keyof T]: StandardSchemaV1.InferOutput<T[K]> };
153-153: Optional: avoidas anyin the standard path.A small typed wrapper keeps local type safety without widening the return to
any.♻️ Possible refactor
+function parseStandardTyped<const T extends Record<string, StandardSchemaV1>>( + def: T, + config: ArkEnvConfig, +): { [K in keyof T]: StandardSchemaV1.InferOutput<T[K]> } { + return parseStandard(def as Record<string, unknown>, config) as { + [K in keyof T]: StandardSchemaV1.InferOutput<T[K]>; + }; +} + if (mode === "standard") { @@ - return parseStandard(def as Record<string, unknown>, config) as any; + return parseStandardTyped(def as Record<string, StandardSchemaV1>, config); }
openspec/changes/fix-standard-mode-inference/specs/inference/spec.md
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@openspec/changes/fix-standard-mode-inference/tasks.md`:
- Around line 2-12: The tasks.md checklist currently uses checked items ("-
[x]") which violates the guideline; update all checklist entries in
openspec/changes/fix-standard-mode-inference/tasks.md to use unchecked items ("-
[ ]") instead (replace every "- [x]" with "- [ ]"), ensuring entries such as
"1.1", "2.1"–"2.3", and "3.1"–"3.3" are converted so the file follows the
required unchecked checklist format.
- Use `as any` for createEnv calls - Resolve union type overload issues - Simplify ArkEnvConfig definition
- Correctly infers types from Standard Schema validators - Avoids wrapping types in ArkType-specific wrappers
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## arkenv@0.9.1 ### Patch Changes - #### Fix Standard Schema type inference _[`#758`](#758) [`3b747b0`](3b747b0) [@yamcodes](https://github.com/yamcodes)_ Fixed type inference when using `validator: "standard"` mode. The `env` object now correctly infers types from Standard Schema validators like Zod or Valibot. ## @arkenv/bun-plugin@0.1.1 ### Patch Changes - #### Support configuration _[`#763`](#763) [`06de0ef`](06de0ef) [@yamcodes](https://github.com/yamcodes)_ Add support for an optional configuration object as the second argument. This allows you to set the `validator` mode to `"standard"`, enabling support for libraries like Zod or Valibot without an ArkType dependency. ```ts import { z } from "zod"; import arkenv from "@arkenv/bun-plugin"; arkenv( { BUN_PUBLIC_API_URL: z.string().url(), }, { validator: "standard", } ); ``` <details><summary>Updated 1 dependency</summary> <small> [`3b747b0`](3b747b0) </small> - `arkenv@0.9.1` </details> ## @arkenv/vite-plugin@0.0.28 ### Patch Changes - #### Support configuration _[`bb832b1`](bb832b1) [@yamcodes](https://github.com/yamcodes)_ Add support for an optional configuration object as the second argument. This allows you to set the `validator` mode to `"standard"`, enabling support for libraries like Zod or Valibot without an ArkType dependency. ```ts import { z } from "zod"; import arkenvVitePlugin from "@arkenv/vite-plugin"; arkenvVitePlugin( { VITE_API_URL: z.string().url(), }, { validator: "standard", } ); ``` <details><summary>Updated 1 dependency</summary> <small> [`3b747b0`](3b747b0) </small> - `arkenv@0.9.1` </details> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## Summary
- Reorder `createEnv` overloads so the inline `EnvSchema<T>` overload is
evaluated first, restoring ArkType DSL string autocomplete
- Narrow the `config` parameter on ArkType-specific overloads to `{
validator?: "arktype" }` so they don't greedily match `{ validator:
"standard" }` calls — preserving correct return type inference for
standard mode (#758)
Closes #790
## Context
This is the same autocomplete regression originally reported in #522 and
fixed in #531 (v0.7.8). It regressed when #758 moved the
`StandardSchemaV1` overload to first position to fix standard mode
return types. The root cause was that overload ordering was the *only*
mechanism disambiguating the two modes — this fix makes the overloads
mutually exclusive via their config types, so ordering is no longer a
correctness concern.
## Test plan
- [x] All 227 arkenv tests pass (including standard mode type inference
tests with `expectTypeOf`)
- [x] Full monorepo test suite passes (6/6 projects)
- [x] Manually verified inline schema autocomplete works in editor
- [x] Manually verified standard mode return type inference works in
editor
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Bug Fixes**
* Fixed inline schema autocompletion functionality for ArkType DSL
strings when using arkenv() with inline schema objects.
* **Refactor**
* Improved createEnv function by narrowing overloads based on validator
configuration type. Overloads are now mutually exclusive and
order-independent.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary by CodeRabbit
New Features
Documentation
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.