From 3013ada8f8d4227f6ca7cc62dbd60d273cf62cde Mon Sep 17 00:00:00 2001 From: OKURA Masafumi Date: Thu, 21 Nov 2024 02:54:28 +0900 Subject: [PATCH] feat: Allow recursive type definition Let's say we have the following type: ```typescript type Chapter = { title: string next: Chapter | null } ``` Here, `Chapter` type is recursive, referencing itself. Typelizer can generate this kind of type, but currently it tries to import itself and causes an error. This commit fixes this issue by ignoring itself from import target. Note that I added spec for Alba only since that was my case, but please tell me if I should add more specs for other serializers. --- lib/typelizer/interface.rb | 6 +++++- spec/__snapshots__/AlbaPost.ts.snap | 3 ++- spec/app/app/models/post.rb | 6 +++++- spec/app/app/serializers/alba/post_serializer.rb | 7 ++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/typelizer/interface.rb b/lib/typelizer/interface.rb index 3d735d7..0bebe3a 100644 --- a/lib/typelizer/interface.rb +++ b/lib/typelizer/interface.rb @@ -66,7 +66,7 @@ def imports .uniq .reject { |type| global_type?(type) } - (custom_type_imports + serializer_types).uniq + (custom_type_imports + serializer_types).uniq - Array(self_type_name) end def inspect @@ -75,6 +75,10 @@ def inspect private + def self_type_name + serializer.name.match(/(\w+::)?(\w+)(Serializer|Resource)/)[2] + end + def extract_typescript_types(type) type.split(/[<>\[\],\s|]+/) end diff --git a/spec/__snapshots__/AlbaPost.ts.snap b/spec/__snapshots__/AlbaPost.ts.snap index e73df7c..d444374 100644 --- a/spec/__snapshots__/AlbaPost.ts.snap +++ b/spec/__snapshots__/AlbaPost.ts.snap @@ -1,4 +1,4 @@ -// Typelizer digest a9453a41deef37fc65276aad80c95e46 +// Typelizer digest c272bbef7d366eb5882788757480509d // // DO NOT MODIFY: This file was automatically generated by Typelizer. import type {AlbaUser} from '@/types' @@ -10,6 +10,7 @@ type AlbaPost = { body?: string | null; published_at?: string | null; user: AlbaUser; + next_post: Post; } export default AlbaPost; diff --git a/spec/app/app/models/post.rb b/spec/app/app/models/post.rb index 952858d..0d6c03f 100644 --- a/spec/app/app/models/post.rb +++ b/spec/app/app/models/post.rb @@ -1,5 +1,9 @@ class Post < ApplicationRecord belongs_to :user - enum category: [:news, :article, :blog].index_by(&:itself) + enum category: %i[news article blog].index_by(&:itself) + + def next_post + # Returns Post + end end diff --git a/spec/app/app/serializers/alba/post_serializer.rb b/spec/app/app/serializers/alba/post_serializer.rb index aebd497..691b9ba 100644 --- a/spec/app/app/serializers/alba/post_serializer.rb +++ b/spec/app/app/serializers/alba/post_serializer.rb @@ -5,11 +5,16 @@ class PostSerializer typelizer_config do |c| c.null_strategy = :nullable_and_optional - c.serializer_model_mapper = ->(serializer) { Object.const_get(serializer.name.gsub("Serializer", "").gsub("Alba::", "")) } + c.serializer_model_mapper = lambda { |serializer| + Object.const_get(serializer.name.gsub("Serializer", "").gsub("Alba::", "")) + } end attributes :id, :title, :category, :body, :published_at has_one :user, serializer: UserSerializer + + attributes :next_post + typelize next_post: "Post" end end