{"id":11146,"library":"joi-to-typescript","title":"Joi to TypeScript Interface Converter","description":"joi-to-typescript is a utility library designed to automatically generate TypeScript interfaces from Joi validation schemas. Its primary purpose is to eliminate the redundancy of manually defining both Joi schemas for runtime validation and TypeScript interfaces for compile-time type checking, adhering to the DRY (Don't Repeat Yourself) principle. The current stable version is 4.15.0, with frequent minor and patch releases addressing dependency updates and feature enhancements. It is built to work seamlessly with Joi v17.x and is particularly useful in ecosystems like Hapi.js, offering integrations with tools like `joi-to-swagger` and `hapi-swagger` by leveraging Joi's `.meta()` functionality for interface naming and structure.","status":"active","version":"4.15.0","language":"javascript","source_language":"en","source_url":"https://github.com/mrjono1/joi-to-typescript","tags":["javascript","joi","ts","typescript","hapi","interface"],"install":[{"cmd":"npm install joi-to-typescript","lang":"bash","label":"npm"},{"cmd":"yarn add joi-to-typescript","lang":"bash","label":"yarn"},{"cmd":"pnpm add joi-to-typescript","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required peer dependency for defining Joi schemas which this library converts.","package":"joi","optional":false}],"imports":[{"note":"The primary function to initiate schema conversion. Supports ESM imports.","wrong":"const { convert } = require('joi-to-typescript');","symbol":"convert","correct":"import { convert } from 'joi-to-typescript';"},{"note":"Used for defining the Joi schemas themselves. Ensure 'joi' is installed as a direct dependency.","wrong":"const Joi = require('joi');","symbol":"Joi","correct":"import Joi from 'joi';"},{"note":"Interface describing the type information returned by the conversion process.","symbol":"ITypeInfo","correct":"import { ITypeInfo } from 'joi-to-typescript';"}],"quickstart":{"code":"import Joi from 'joi';\nimport { convert } from 'joi-to-typescript';\n\n// Define your Joi schemas with .meta({ className: '...' }) for interface names\nexport const JobSchema = Joi.object({\n  businessName: Joi.string().required(),\n  jobTitle: Joi.string().required()\n}).meta({ className: 'Job' });\n\nexport const WalletSchema = Joi.object({\n  usd: Joi.number().required(),\n  eur: Joi.number().required()\n})\n  .unknown() // Example with unknown keys\n  .meta({ className: 'Wallet', unknownType: 'number' }); // Specify type for unknown keys\n\nexport const PersonSchema = Joi.object({\n  firstName: Joi.string().required(),\n  lastName: Joi.string().required().description('Last Name'),\n  job: JobSchema, // Nested schema\n  wallet: WalletSchema\n}).meta({ className: 'Person' });\n\n// Use the convert function to generate TypeScript interfaces\nconst { typescript: jobInterface } = convert(JobSchema);\nconst { typescript: walletInterface } = convert(WalletSchema);\nconst { typescript: personInterface } = convert(PersonSchema);\n\nconsole.log('// Job Interface');\nconsole.log(jobInterface);\nconsole.log('\\n// Wallet Interface');\nconsole.log(walletInterface);\nconsole.log('\\n// Person Interface');\nconsole.log(personInterface);\n\n/* Expected output will resemble:\n// Job Interface\nexport interface Job {\n  businessName: string;\n  jobTitle: string;\n}\n\n// Wallet Interface\nexport interface Wallet {\n  usd: number;\n  eur: number;\n  [x: string]: number;\n}\n\n// Person Interface\nexport interface Person {\n  firstName: string;\n  lastName: string;\n  job?: Job;\n  wallet?: Wallet;\n}\n*/","lang":"typescript","description":"Demonstrates defining Joi schemas, including nested objects and unknown properties, and then using `joi-to-typescript`'s `convert` function to generate corresponding TypeScript interfaces."},"warnings":[{"fix":"Ensure `joi@17.x` is installed in your project's dependencies: `npm install joi@^17` or `yarn add joi@^17`.","message":"This package requires Joi version 17.x as a peer dependency. Using older or incompatible versions of Joi will likely result in conversion errors or incorrect type generation.","severity":"gotcha","affected_versions":">=4.0.0"},{"fix":"Install with `npm install --save-dev joi-to-typescript` and `npm install joi` (or `yarn add --dev joi-to-typescript` and `yarn add joi`).","message":"joi-to-typescript is intended as a development-time tool. It should be installed as a `devDependency`, while `joi` itself (the peer dependency) should be installed as a regular `dependency`.","severity":"gotcha","affected_versions":">=4.0.0"},{"fix":"Replace `.label('...')` with `.meta({ className: '...' })` for naming interfaces.","message":"For defining interface names, always use `.meta({ className: 'YourInterfaceName' })` on your Joi schemas. Using `.label()` for this purpose is discouraged as it interferes with Joi's intended use for error messages and might lead to unexpected behavior or conflicts with other tools like `hapi-swagger`.","severity":"gotcha","affected_versions":">=4.0.0"},{"fix":"Upgrade your Node.js environment to version 18 or 20 for optimal compatibility and support.","message":"The library explicitly supports Node.js versions 18 and 20. While the `engines` field in `package.json` might indicate `>=14.0.0`, official support focuses on these newer LTS versions. Using older Node.js environments may lead to unexpected issues.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Add `.meta({ unknownType: 'string' })` (or appropriate type) to Joi schemas using `.unknown()`.","message":"When dealing with Joi objects that allow unknown keys via `.unknown()`, you can specify the type for these unknown keys using `.meta({ unknownType: 'your_type' })` to ensure the generated TypeScript interface accurately reflects this. Without it, the generated type for unknown keys might default to `any` or be less specific.","severity":"gotcha","affected_versions":">=4.12.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using `import Joi from 'joi';` for ESM projects and that `joi@17.x` is correctly installed.","cause":"Incorrect Joi import statement (e.g., using `require` for a module that only exports ES modules) or a mismatch in Joi versions between runtime and type definitions.","error":"TypeError: joi_1.default.validate is not a function"},{"fix":"Install Joi: `npm install joi` or `yarn add joi`.","cause":"The `joi` package, a required peer dependency, is not installed in the project's dependencies.","error":"Error: Cannot find module 'joi'"},{"fix":"Ensure all root-level schemas intended to become interfaces have `.meta({ className: 'YourInterfaceName' })`. Check the documentation for supported Joi features and consider breaking down very complex schemas if issues persist.","cause":"The Joi schema might be missing `.meta({ className: 'InterfaceName' })`, or it's a complex schema feature not fully supported by `joi-to-typescript` yet, or Joi's `.label()` was used instead of `.meta()` for naming.","error":"Generated TypeScript interface is empty or 'any'"}],"ecosystem":"npm"}