Skip to content

feat: type inference for check function#355

Open
Laurin-W wants to merge 2 commits into
icebob:masterfrom
Laurin-W:feat/schema-type-inference
Open

feat: type inference for check function#355
Laurin-W wants to merge 2 commits into
icebob:masterfrom
Laurin-W:feat/schema-type-inference

Conversation

@Laurin-W
Copy link
Copy Markdown

@Laurin-W Laurin-W commented Nov 8, 2025

The PR adds utility types that can infer the TypeScript types from validation schemas.

This is the type inference part that is eventually intended to be used in moleculer to infer the parameter types of action handlers.

I modified the compile() function of the Validator so that the returned check function expects the TS type that was specified in the schema passed to compile().
If you prefer to not have this implemented with the check()/compile() function, let me know. We could also just export the utility types for external use (by moleculer).

Note that the inference types do not support all features that the validator does. For example, "email" or "uuid" are interpreted as string.
Also, type inference for validators with the considerNullAsAValue flag are not implemented (it does not seem to be a very common use case and the complexity would grow. Let me know if you think it should be implemented).

This is WIP.
The TS unit tests are not yet adapted (they will require // @ts-expect-error comments for check() calls with invalid objects).

@Laurin-W Laurin-W marked this pull request as ready for review December 15, 2025 10:35
@Laurin-W
Copy link
Copy Markdown
Author

Hello everyone,
this PR is now ready for review.

The TypeScript tests are updated and you can play around with them to see what it "feels like" working with the inferred TS types.

Note that I did not add support for the validate() function because it would cause "type instantiation is excessively deep and possibly infinite" errors. So type inference is supported by the function returned by compile() only.

Happy to hear about your feedback and let me know if you have questions!


Btw, the TypeScript 7 native implementation is in a usable state now and a charm to play with (since it's ~10x faster, everything feels more "instant").
The minimum required TS version is 4.9.0.

@Laurin-W
Copy link
Copy Markdown
Author

Laurin-W commented Jan 8, 2026

Hey @icebob, I was wondering if you have any update on this? :)

Copy link
Copy Markdown
Collaborator

@icebob-ai icebob-ai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this excellent work, @Laurin-W! The type inference system is really well designed — the TypeFromValidationSchema / TypeFromValidationRule utility types handle arrays, multi-rules, objects, enums, class instances, convert mode, and optional/nullable correctly. This is a high-value addition and we'd love to merge it.

However, there are a few things to address before we can merge:

1. Remove unused import

import type { EnumType } from "typescript";

This import doesn't appear to be used anywhere in the file, and it would break users who don't have typescript as a dependency (it's only a devDependency for most projects).

2. Separate formatting changes from functional changes

The current diff is ~33K lines, but almost all of it is whitespace reformatting (tab normalization) in index.d.ts. This makes it very hard to review the actual functional changes. Could you please:

  • Revert the whitespace-only changes
  • Keep only the functional additions (the inference types, the generic parameters, the ValidationSchema refactor, etc.)

3. Rebase on current master

Master has changed since this PR was opened (build toolchain migration, new pipe rule). A rebase would resolve potential conflicts and ensure CI runs cleanly.

The core type inference work (~100 lines of utility types) is solid and we're keen to get it merged. Looking forward to the updated PR!

@Laurin-W Laurin-W force-pushed the feat/schema-type-inference branch from 39c979e to c85c835 Compare April 7, 2026 11:04
@Laurin-W
Copy link
Copy Markdown
Author

Laurin-W commented Apr 7, 2026

Hi @icebob-ai,

thanks for your reply and sorry for the formatting issues.

I force-pushed a new commit where the formatting changes and unused imports are removed and the branch is rebased on next.

Let me know if you need anything else.

Best,
Laurin

- Add inference types (`TypeFromValidationSchema`, ...)
- Validator.compile and validate functions infer allowable type
- Update TypeScript tests with`@ts-expect-error` and more specific schema definitions using `as const` and `satisfies`
@Laurin-W Laurin-W force-pushed the feat/schema-type-inference branch from c85c835 to d35b43f Compare April 7, 2026 11:24
@icebob-ai
Copy link
Copy Markdown
Collaborator

Thanks for the updated PR, @Laurin-W! The formatting cleanup and rebase look good.

However, I noticed that the ValidationSchema<T> generic parameter is removed in this PR — the old signature was:

type ValidationSchema<T = any> = ValidationSchemaMetaKeys & {
    [key in keyof T]: ValidationRule | undefined;
}

and it's now replaced with a non-generic ValidationSchema union type. This is a breaking change for anyone who uses ValidationSchema<MyType> in their code.

Since all current changes on master are backward-compatible (new features + bugfixes), I'd like to release them as 1.x. This PR would require a major version bump (2.0), which I'd prefer to avoid if possible.

Could you rework this so the ValidationSchema<T> generic signature is preserved (or at least kept as a compatible alias)? The inference types themselves are great — I just need the public API surface to stay backward-compatible so this can land in a minor release.

Let me know if you have questions or need help with this!

@Laurin-W
Copy link
Copy Markdown
Author

Hi @icebob-ai, thanks for the heads up!
I re-added the generic type parameter. It is passed on to ValidationSchemaNested<T = any> where keyof T is used again as before.

@Laurin-W Laurin-W requested a review from icebob-ai April 21, 2026 06:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants