Skip to content

feat: improve TypeScript type inference to Joi schemas#3104

Open
damusix wants to merge 3 commits into
hapijs:masterfrom
damusix:fix/types
Open

feat: improve TypeScript type inference to Joi schemas#3104
damusix wants to merge 3 commits into
hapijs:masterfrom
damusix:fix/types

Conversation

@damusix
Copy link
Copy Markdown

@damusix damusix commented Mar 24, 2026

Improve compile-time type inference so Joi.inferType extracts correct TypeScript types from schema definitions. validate().value and Joi.attempt() now return inferred types instead of any.

  • Phantom type properties (~output, ~input, ~flags) on AnySchema
  • SchemaFlags with presence, hasDefault, isStripped tracking
  • Intersection return types for .required(), .optional(), .forbidden(), .strip(), .default(), .failover(), .valid()
  • Joi.object() captures schema map via TShape generic
  • InferObjectOutput splits keys into required/optional
  • .keys(), .append(), .concat() preserve shape inference
  • .ordered() infers tuples, .sparse() adds undefined
  • .when() infers union of then/otherwise branches
  • InferType, InferInput, InferOutput utility types
  • Typed Joi.assert() with type narrowing assertion
  • Joi.extend() returns Root & TypeMap
  • Input/output distinction for .default()
  • Exhaustive negative tests (expect.error) proving inference is real

@damusix damusix changed the title feat: add TypeScript type inference to Joi schemas feat: improve TypeScript type inference to Joi schemas Mar 24, 2026
Improve compile-time type inference for Joi.inferType<typeof schema>
correct TypeScript types from schema definitions. validate().value and
Joi.attempt() now return inferred types instead of any.

- Phantom type properties (~output, ~input, ~flags) on AnySchema
- SchemaFlags with presence, hasDefault, isStripped tracking
- Intersection return types for .required(), .optional(), .forbidden(),
  .strip(), .default(), .failover(), .valid()
- Joi.object() captures schema map via TShape generic
- InferObjectOutput splits keys into required/optional
- .keys(), .append(), .concat() preserve shape inference
- .ordered() infers tuples, .sparse() adds undefined
- .when() infers union of then/otherwise branches
- InferType, InferInput, InferOutput utility types
- Typed Joi.assert() with type narrowing assertion
- Joi.extend<TypeMap>() returns Root & TypeMap
- Input/output distinction for .default()
- Exhaustive negative tests (expect.error) proving inference is real
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