{"id":14020080,"url":"https://github.com/skryukov/typelizer","last_synced_at":"2026-02-26T13:02:43.138Z","repository":{"id":251331818,"uuid":"837119942","full_name":"skryukov/typelizer","owner":"skryukov","description":"A TypeScript type generator for Ruby serializers.","archived":false,"fork":false,"pushed_at":"2026-02-18T11:08:41.000Z","size":257,"stargazers_count":208,"open_issues_count":3,"forks_count":16,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-18T15:46:11.610Z","etag":null,"topics":["alba","ams","hacktoberfest","rails","ruby","typescript"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skryukov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-08-02T08:56:55.000Z","updated_at":"2026-02-08T15:49:23.000Z","dependencies_parsed_at":"2026-02-18T13:04:11.064Z","dependency_job_id":null,"html_url":"https://github.com/skryukov/typelizer","commit_stats":{"total_commits":8,"total_committers":3,"mean_commits":"2.6666666666666665","dds":0.25,"last_synced_commit":"52840713e3456f96ca9e8601d33ab2f494b83ddc"},"previous_names":["skryukov/typelizer"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/skryukov/typelizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skryukov%2Ftypelizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skryukov%2Ftypelizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skryukov%2Ftypelizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skryukov%2Ftypelizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skryukov","download_url":"https://codeload.github.com/skryukov/typelizer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skryukov%2Ftypelizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29614634,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T13:04:20.082Z","status":"ssl_error","status_checked_at":"2026-02-19T13:03:33.775Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alba","ams","hacktoberfest","rails","ruby","typescript"],"created_at":"2024-08-11T13:01:12.041Z","updated_at":"2026-02-26T13:02:43.130Z","avatar_url":"https://github.com/skryukov.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Typelizer\n\n[![Gem Version](https://badge.fury.io/rb/typelizer.svg)](https://rubygems.org/gems/typelizer)\n\nTypelizer generates TypeScript types from your Ruby serializers. It supports multiple serializer libraries and a flexible, layered configuration model so you can keep your backend and frontend in sync without hand‑maintaining types.\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Basic Setup](#basic-setup)\n  - [Manual Typing](#manual-typing)\n  - [Alba Traits](#alba-traits)\n  - [TypeScript Integration](#typescript-integration)\n  - [Manual Generation](#manual-generation)\n  - [Automatic Generation in Development](#automatic-generation-in-development)\n  - [Disabling Typelizer](#disabling-typelizer)\n- [OpenAPI Schema Generation](#openapi-schema-generation)\n- [Configuration](#configuration)\n  - [Global Configuration](#simple-configuration)\n  - [Writers (multiple outputs)](#defining-multiple-writers)\n  - [Per-Serializer Configuration](#per-serializer-configuration)\n- [Credits](#credits)\n- [License](#license)\n\n\u003ca href=\"https://evilmartians.com/?utm_source=typelizer\u0026utm_campaign=project_page\"\u003e\n\u003cimg src=\"https://evilmartians.com/badges/sponsored-by-evil-martians.svg\" alt=\"Built by Evil Martians\" width=\"236\" height=\"54\"\u003e\n\u003c/a\u003e\n\n## Features\n\n- Automatic TypeScript interface generation\n- Infers types from database columns and associations, with support for the Attributes API\n- Supports multiple serializer libraries (`Alba`, `ActiveModel::Serializer`, `Oj::Serializer`, `Panko::Serializer`)\n- File watching with automatic regeneration in development\n- Multiple output writers: emit several variants (e.g., snake_case and camelCase) in parallel\n\n## Installation\n\nTo install Typelizer, add the following line to your `Gemfile` and run `bundle install`:\n\n```ruby\ngem \"typelizer\"\n```\n\n## Usage\n\n### Basic Setup\n\nInclude the Typelizer DSL in your serializers:\n\n```ruby\nclass ApplicationResource\n  include Alba::Resource\n  include Typelizer::DSL\n\n  # For Alba, we recommend using the `helper` method instead of `include`.\n  # See the documentation: https://github.com/okuramasafumi/alba/blob/main/README.md#helper\n  # helper Typelizer::DSL\nend\n\nclass PostResource \u003c ApplicationResource\n  attributes :id, :title, :body\n\n  has_one :author, serializer: AuthorResource\nend\n\nclass AuthorResource \u003c ApplicationResource\n  # specify the model to infer types from (optional)\n  typelize_from User\n\n  attributes :id, :name\nend\n```\n\nTypelizer will automatically generate TypeScript interfaces based on your serializer definitions using information from your models.\n\n### Manual Typing\n\nYou can manually specify TypeScript types in your serializers:\n\n```ruby\nclass PostResource \u003c ApplicationResource\n  attributes :id, :title, :body, :published_at\n\n  typelize \"string\"\n  attribute :author_name do |post|\n    post.author.name\n  end\n\n  typelize :string, nullable: true, comment: \"Author's avatar URL\"\n  attribute :avatar do\n    \"https://example.com/avatar.png\" if active?\n  end\nend\n```\n\n`typelize` can be used with a Hash to specify multiple types at once.\n\n```ruby\nclass PostResource \u003c ApplicationResource\n  attributes :id, :title, :body, :published_at\n\n  attribute :author_name do |post|\n    post.author.name\n  end\n\n  typelize author_name: :string, published_at: :string\nend\n```\n\nYou can also use shortcut syntax for common type modifiers:\n\n```ruby\nclass PostResource \u003c ApplicationResource\n  typelize author_name: \"string?\"       # optional string (name?: string)\n  typelize tag_ids: \"number[]\"          # array of numbers (tag_ids: Array\u003cnumber\u003e)\n  typelize categories: \"string?[]\"      # optional array of strings (categories?: Array\u003cstring\u003e)\n\n  # Shortcuts can be combined with explicit options\n  typelize status: [\"string?\", nullable: true]  # optional and nullable\n\n  # Also works with keyless typelize\n  typelize \"string?\"\n  attribute :nickname do |user|\n    user.nickname\n  end\nend\n```\n\nYou can reference other serializers directly by passing the class. Typelizer resolves the class to its generated type name automatically:\n\n```ruby\nclass PostResource \u003c ApplicationResource\n  attributes :id, :title\n\n  # Reference another serializer — resolves to its generated TypeScript type\n  typelize reviewer: [AuthorResource, {optional: true, nullable: true}]\n  attribute :reviewer do |post|\n    post.reviewer\n  end\n\n  # Self-reference works too\n  typelize previous_post: PostResource\n  attribute :previous_post do |post|\n    post.previous_post\n  end\nend\n```\n\nUnion types are supported for polymorphic associations. You can use serializer class references, which resolve to their generated type names:\n\n```ruby\nclass PostResource \u003c ApplicationResource\n  attributes :id, :title\n\n  # Union of two serializers — resolves to generated type names\n  typelize commentable: [UserResource, CommentResource]\n  attribute :commentable\n\n  # Nullable union — extracts null and marks as nullable\n  typelize approver: \"AuthorResource | null\"\n  attribute :approver\n\n  # Pipe-delimited string with serializer names\n  typelize target: \"UserResource | CommentResource\"\n  attribute :target\n\n  # String and class constant can be mixed\n  typelize item: [\"Namespace::UserResource\", CommentResource]\n  attribute :item\nend\n```\n\nYou can also use plain TypeScript type names for custom types that aren't backed by serializers:\n\n```ruby\nclass PostResource \u003c ApplicationResource\n  attributes :id, :title\n\n  # Plain type names — passed through as-is to TypeScript\n  typelize content: \"TextBlock | ImageBlock\"\n  attribute :content\n\n  # Works with arrays too\n  typelize sections: [\"TextBlock\", \"ImageBlock\"]\n  attribute :sections\nend\n```\n\nThis generates:\n\n```typescript\ntype Post = {\n  id: number;\n  title: string;\n  content: TextBlock | ImageBlock;\n  sections: TextBlock | ImageBlock;\n}\n```\n\nFor more complex type definitions, use the full API:\n\n```ruby\ntypelize attribute_name: [\"string\", \"Date\", optional: true, nullable: true, multi: true, enum: %w[foo bar], comment: \"Attribute description\", deprecated: \"Use `another_attribute` instead\"]\n```\n\n### Alba Traits\n\nTypelizer supports [Alba traits](https://github.com/okuramasafumi/alba#traits), generating separate TypeScript types for each trait. When using `with_traits` in associations, Typelizer generates intersection types.\n\n```ruby\nclass UserResource \u003c ApplicationResource\n  attributes :id, :name\n\n  trait :detailed do\n    attributes :email, :created_at\n  end\n\n  trait :with_posts do\n    has_many :posts, resource: PostResource, with_traits: [:summary]\n  end\nend\n```\n\nThis generates:\n\n```typescript\n// User.ts\nexport type User = {\n  id: number;\n  name: string;\n}\n\ntype UserDetailedTrait = {\n  email: string;\n  created_at: string;\n}\n\ntype UserWithPostsTrait = {\n  posts: Array\u003cPost \u0026 PostSummaryTrait\u003e;\n}\n\nexport default User;\n```\n\nWhen using `with_traits` in associations, Typelizer generates intersection types combining the base type with trait types:\n\n```ruby\nclass TeamResource \u003c ApplicationResource\n  attributes :id, :name\n  has_one :lead, resource: UserResource, with_traits: [:detailed]\n  has_many :members, resource: UserResource, with_traits: [:detailed, :with_posts]\nend\n```\n\nThis generates:\n\n```typescript\n// Team.ts\nimport type { User, UserDetailedTrait, UserWithPostsTrait } from \"@/types\";\n\nexport type Team = {\n  id: number;\n  name: string;\n  lead: User \u0026 UserDetailedTrait;\n  members: Array\u003cUser \u0026 UserDetailedTrait \u0026 UserWithPostsTrait\u003e;\n}\n\nexport default Team;\n```\n\nThe `typelize` method works inside traits for manual type specification:\n\n```ruby\ntrait :with_stats do\n  typelize :number\n  attribute :posts_count do |user|\n    user.posts.count\n  end\n\n  typelize score: :number\n  attributes :score\nend\n```\n\n### TypeScript Integration\n\nTypelizer generates TypeScript interfaces in the specified output directory:\n\n```typescript\n// app/javascript/types/serializers/Post.ts\nexport interface Post {\n  id: number;\n  title: string;\n  category?: \"news\" | \"article\" | \"blog\" | null;\n  body: string;\n  published_at: string | null;\n  author_name: string;\n}\n```\n\nAll generated interfaces are automatically imported in a single file:\n\n```typescript\n// app/javascript/types/serializers/index.ts\nexport * from \"./post\";\nexport * from \"./author\";\n```\n\nWe recommend importing this file in a central location:\n\n```typescript\n// app/javascript/types/index.ts\nimport \"@/types/serializers\";\n// Custom types can be added here\n// ...\n```\n\nWith such a setup, you can import all generated interfaces in your TypeScript files:\n\n```typescript\nimport { Post } from \"@/types\";\n```\n\nThis setup also allows you to use custom types in your serializers:\n\n```ruby\nclass PostWithMetaResource \u003c ApplicationResource\n  attributes :id, :title\n  typelize \"PostMeta\"\n  attribute :meta do |post|\n    { likes: post.likes, comments: post.comments }\n  end\nend\n```\n\n```typescript\n// app/javascript/types/serializers/PostWithMeta.ts\n\nimport { PostMeta } from \"@/types\";\n\nexport interface Post {\n  id: number;\n  title: string;\n  meta: PostMeta;\n}\n```\n\nThe `\"@/types\"` import path is configurable:\n\n```ruby\nTypelizer.configure do |config|\n  config.types_import_path = \"@/types\";\nend\n```\n\nSee the [Configuration](#configuration) section for more options.\n\n### Manual Generation\n\nTo manually generate TypeScript interfaces use one of the following commands:\n\n```bash\n# Generate new interfaces\nrails typelizer:generate\n\n# Clean output directory and regenerate all interfaces\nrails typelizer:generate:refresh\n````\n\n### Automatic Generation in Development\n\nWhen [Listen](https://github.com/guard/listen) is installed, Typelizer automatically watches for changes and regenerates interfaces in development mode. You can disable this behavior:\n\n```ruby\nTypelizer.listen = false\n```\n\n### Disabling Typelizer\n\nSometimes we want to use Typelizer only with manual generation. To disable Typelizer during development, we can set `DISABLE_TYPELIZER` environment variable to `true`. This doesn't affect manual generation.\n\n## OpenAPI Schema Generation\n\nTypelizer can generate [OpenAPI](https://swagger.io/specification/) component schemas from your serializers. This is useful for documenting your API or integrating with tools like [rswag](https://github.com/rswag/rswag).\n\nGet all schemas as a hash:\n\n```ruby\nTypelizer.openapi_schemas\n# =\u003e {\n#   \"Post\" =\u003e {\n#     type: :object,\n#     properties: {\n#       id: { type: :integer },\n#       title: { type: :string },\n#       published_at: { type: :string, format: :\"date-time\", nullable: true }\n#     },\n#     required: [:id, :title]\n#   },\n#   \"Author\" =\u003e { ... }\n# }\n```\n\nBy default, schemas are generated for OpenAPI 3.0. Pass `openapi_version: \"3.1\"` for OpenAPI 3.1 output (e.g., `type: [:string, :null]` instead of `nullable: true`):\n\n```ruby\nTypelizer.openapi_schemas(openapi_version: \"3.1\")\n```\n\nGenerate a schema for a single interface:\n\n```ruby\ninterfaces = Typelizer.interfaces\npost_interface = interfaces.find { |i| i.name == \"Post\" }\nTypelizer::OpenAPI.schema_for(post_interface)\nTypelizer::OpenAPI.schema_for(post_interface, openapi_version: \"3.1\")\n```\n\nColumn types are mapped to OpenAPI types automatically:\n\n| Column type | OpenAPI type | Format |\n|---|---|---|\n| `integer` | `integer` | |\n| `bigint` | `integer` | `int64` |\n| `float` | `number` | `float` |\n| `decimal` | `number` | `double` |\n| `boolean` | `boolean` | |\n| `string`, `text`, `citext` | `string` | |\n| `uuid` | `string` | `uuid` |\n| `date` | `string` | `date` |\n| `datetime` | `string` | `date-time` |\n| `time` | `string` | `time` |\n\nEnums, nullable fields, arrays, deprecated flags, and `$ref` associations are all handled automatically.\n\n## Configuration\n\nTypelizer provides several global configuration options:\n\n```ruby\n# Directories to search for serializers:\nTypelizer.dirs = [Rails.root.join(\"app\", \"resources\"), Rails.root.join(\"app\", \"serializers\")]\n# Reject specific classes from being typelized:\nTypelizer.reject_class = -\u003e(serializer:) { false }\n# Logger for debugging:\nTypelizer.logger = Logger.new($stdout, level: :info)\n# Force enable or disable file watching with Listen:\nTypelizer.listen = nil\n```\n\n### Configuration Layers\n\nTypelizer uses a hierarchical system to resolve settings. Settings are applied in the following order of precedence, where higher numbers override lower ones:\n\n1.  **Per-Serializer Overrides**: Settings defined using `typelizer_config` directly within a serializer class. This layer has the highest priority.\n2.  **Writer-Specific Settings**: Settings defined within a `config.writer(:name) { ... }` block.\n3.  **Global Settings**: Application-wide settings defined by direct assignment (e.g., `config.comments = true`) within the `Typelizer.configure` block.\n4.  **Library Defaults**: The gem's built-in default values.\n\n### Simple Configuration (Single Output)\n\nFor most apps, a single output is enough. All settings in an initializer apply to the `:default` writer and also act as a global baseline.\n\n- Settings like `dirs` are considered **Global** and establish a baseline for all writers.\n- Settings like `output_dir` or `comments` configure the implicit **`:default` writer**.\n\n```ruby\n# config/initializers/typelizer.rb\nTypelizer.configure do |config|\n  # This is a GLOBAL SETTING. It applies to ALL writers.\n  config.dirs = [Rails.root.join(\"app/serializers\")]\n\n  # This setting configures the :default writer and ALSO acts as a global setting.\n  config.output_dir = \"app/javascript/types/generated\"\n  config.comments = true\nend\n```\n\n### Defining Multiple Writers\n\nThe multi-writer system allows for the generation of multiple, distinct TypeScript outputs. Each output is managed by a named writer with an isolated configuration.\n\n\n#### Writer Inheritance Rules\n\n- By default, a new writer inherits its base settings from the Global Settings.\n- To inherit from another existing writer, use the `from:` option.\n\n\n**A Note on the :default Writer and Inheritance**\n- You usually do not need to declare `writer(:default)`. The implicit default writer automatically uses your global settings. \n- Declare `writer(:default)` when you want to apply specific overrides to it that should not be inherited by other new writers. This provides a way to separate your application's global baseline from settings that are truly unique to the default output\n\n#### Example of the distinction:\n```ruby\nTypelizer.configure do |config|\n  # === Global Setting ===\n  # `comments: true` applies to :default and will be inherited by :camel_case.\n  config.comments = true\n\n  # === Default-Writer-Only Setting ===\n  # `prefer_double_quotes: true` applies ONLY to the :default writer.\n  # It is NOT a global setting and will NOT be inherited by :camel_case.\n  config.writer(:default) do |c|\n    c.prefer_double_quotes = true\n  end\n\n  # === New Writer Definition ===\n  config.writer(:camel_case) do |c|\n    c.output_dir = \"app/javascript/types/camel_case\"\n    # This writer inherits `comments: true` from globals.\n    # It does NOT inherit `prefer_double_quotes: true` from the :default writer's block.\n    # Its `prefer_double_quotes` will be `false` (the library default).\n  end\nend\n```\n\n#### Configuring Writers\nYou can define writers either inside the configure block or directly on the Typelizer module.\n\n1. **Inside the configure block**\n\nThis is the approach for keeping all configuration centralized.\n\n```ruby\n# config/initializers/typelizer.rb\nTypelizer.configure do |config|\n  # ... global settings ...\n\n  config.writer(:camel_case) do |c|\n    c.output_dir = \"app/javascript/types/camel_case\"\n    c.properties_transformer = -\u003e(properties) { # ... transform ... }\n  end\n\n  config.writer(:admin, from: :camel_case) do |c|\n    c.output_dir = \"app/javascript/types/admin\"\n    c.null_strategy = :optional\n  end\nend\n```\n\n2. Top-Level Helper\n\n```ruby\nTypelizer.writer(:admin, from: :default) do |c|\n  c.output_dir = Rails.root.join(\"app/javascript/types/admin\")\n  c.prefer_double_quotes = true\nend\n```\n\n#### Comprehensive Example\nThis example configures three distinct outputs, demonstrating all inheritance mechanisms.\n\n```ruby\n# config/initializers/typelizer.rb\nTypelizer.configure do |config|\n  # === 1. Global Settings (Baseline for ALL writers) ===\n  config.comments = true\n  config.dirs = [Rails.root.join(\"app/serializers\")]\n\n  # === 2. The :default writer (snake_case output) ===\n  config.writer(:default) do |c|\n    c.output_dir = \"app/javascript/types/snake_case\"\n  end\n\n  # === 3. A new :camel_case writer ===\n  # Inherits `comments: true` and `dirs` from the Global Settings.\n  config.writer(:camel_case) do |c|\n    c.output_dir = \"app/javascript/types/camel_case\"\n    c.properties_transformer = lambda do |properties|\n      properties.map { |prop| prop.with_overrides(name: prop.name.to_s.camelize(:lower)) }\n    end\n  end\n\n  # === 4. An \"admin\" writer that clones :camel_case ===\n  # Use `from:` to explicitly inherit another writer's complete configuration.\n  config.writer(:admin, from: :camel_case) do |c|\n    c.output_dir = \"app/javascript/types/admin\"\n    # This writer inherits the properties_transformer from :camel_case.\n    c.null_strategy = :optional\n  end\nend\n```\n\n### Per-serializer configuration\n\nUse `typelizer_config` within a serializer class to apply overrides with the highest possible priority. \nThese settings will supersede any conflicting settings from the active writer, global settings, or library defaults.\n\n```ruby\nclass PostResource \u003c ApplicationResource\n  typelizer_config do |c|\n    c.null_strategy = :nullable_and_optional\n    c.plugin_configs = { alba: { ts_mapper: { \"UUID\" =\u003e { type: :string } } } }\n  end\nend\n```\n\n### Option reference\n\n```ruby\nTypelizer.configure do |config|\n  # Name to type mapping for serializer classes\n  config.serializer_name_mapper = -\u003e(serializer) { ... }\n\n  # Maps serializers to their corresponding model classes\n  config.serializer_model_mapper = -\u003e(serializer) { ... }\n\n  # Custom transformation for generated properties\n  config.properties_transformer = -\u003e(properties) { ... }\n\n  # Strategy for ordering properties in generated TypeScript interfaces\n  # :none - preserve serializer definition order (default)\n  # :alphabetical - sort properties A-Z (case-insensitive)\n  # :id_first_alphabetical - place 'id' first, then sort remaining A-Z\n  # Proc - custom sorting function receiving array of Property objects\n  config.properties_sort_order = :none\n\n  # Strategy for ordering imports in generated TypeScript interfaces\n  # :none - preserve original order (default)\n  # :alphabetical - sort imports A-Z (case-insensitive)\n  # Proc - custom sorting function receiving array of import strings\n  config.imports_sort_order = :none\n\n  # Plugin for model type inference (default: ModelPlugins::Auto)\n  config.model_plugin = Typelizer::ModelPlugins::Auto\n\n  # Plugin for serializer parsing (default: SerializerPlugins::Auto)\n  config.serializer_plugin = Typelizer::SerializerPlugins::Auto\n\n  # Additional configurations for specific plugins\n  config.plugin_configs = { alba: { ts_mapper: {...} } }\n\n  # Custom DB to TypeScript type mapping\n  config.type_mapping = config.type_mapping.merge(jsonb: \"Record\u003cstring, undefined\u003e\", ... )\n\n  # Strategy for handling null values (:nullable, :optional, or :nullable_and_optional)\n  config.null_strategy = :nullable\n\n  # Strategy for handling serializer inheritance (:none, :inheritance)\n  # :none - lists all attributes of the serializer in the type\n  # :inheritance - extends the type from the parent serializer\n  config.inheritance_strategy = :none\n\n  # Strategy for handling `has_one` and `belongs_to` associations nullability (:database, :active_record)\n  # :database - uses the database column nullability\n  # :active_record - uses the `required` / `optional` association options\n  config.associations_strategy = :database\n\n  # Directory where TypeScript interfaces will be generated\n  config.output_dir = Rails.root.join(\"app/javascript/types/serializers\")\n\n  # Import path for generated types in TypeScript files\n  # (e.g., `import { MyType } from \"@/types\"`)\n  config.types_import_path = \"@/types\"\n\n  # List of type names that should be considered global in TypeScript\n  # (i.e. not prefixed with the import path)\n  config.types_global = %w[Array Date Record File FileList]\n\n  # Support TypeScript's Verbatim module syntax option (default: false)\n  # Will change imports and exports of types from default to support this syntax option\n  config.verbatim_module_syntax = false\n\n  # Use double quotes in generated TypeScript interfaces (default: false)\n  config.prefer_double_quotes = false\n\n  # Support comments in generated TypeScript interfaces (default: false)\n  # Will add comments to the generated interfaces\n  config.comments = false\nend\n```\n\n## Credits\n\nTypelizer is inspired by [types_from_serializers](https://github.com/ElMassimo/types_from_serializers).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskryukov%2Ftypelizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskryukov%2Ftypelizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskryukov%2Ftypelizer/lists"}