Add annotations for the alba gem - #422
Merged
Merged
Conversation
Alba ships no Sorbet signatures, so tapioca emits its `Alba::Resource` DSL macros sig-less. Annotate the class-level macros used to define a resource. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mokevnin
force-pushed
the
add-alba-annotations
branch
from
September 6, 2026 16:53
55b203c to
a65c176
Compare
KaanOzkan
reviewed
Sep 9, 2026
| sig do | ||
| params( | ||
| handler: T.nilable(Symbol), | ||
| block: T.nilable(T.proc.params(error: T.untyped, object: T.untyped, key: T.untyped, attribute: T.untyped, resource_class: T.untyped).returns(T::Array[T.untyped])), |
Contributor
There was a problem hiding this comment.
Suggested change
| block: T.nilable(T.proc.params(error: T.untyped, object: T.untyped, key: T.untyped, attribute: T.untyped, resource_class: T.untyped).returns(T::Array[T.untyped])), | |
| block: T.nilable(T.proc.params(error: T.untyped, object: T.untyped, key: T.untyped, attribute: T.untyped, resource_class: T.untyped).returns(T.untyped)), |
Looks like it can return any constant? https://github.com/okuramasafumi/alba/blob/v4.0.0/test/usecases/on_error_test.rb#L60-L63
Contributor
Author
There was a problem hiding this comment.
Good catch — the return goes straight back to the caller, so T::Array[T.untyped] was wrong. Applied in d63f627.
Comment on lines
+8
to
+9
| resource: T.nilable(T.any(Module, String, Proc)), | ||
| serializer: T.nilable(T.any(Module, String, Proc)), |
Contributor
There was a problem hiding this comment.
This seems better
Suggested change
| resource: T.nilable(T.any(Module, String, Proc)), | |
| serializer: T.nilable(T.any(Module, String, Proc)), | |
| resource: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), | |
| serializer: T.nilable(T.any(T::Class[Alba::Resource], String, Proc)), |
Contributor
There was a problem hiding this comment.
Similarly for one, has_many, has_one, many
Contributor
Author
There was a problem hiding this comment.
Agreed, T::Class[Alba::Resource] is the honest type. Applied in d63f627.
Contributor
Author
There was a problem hiding this comment.
Done — association, one, many, has_one and has_many all carry the same signature now. bundle exec repo check --gem alba is green.
Address review: resource:/serializer: take a resource class, not any Module, on association and all four aliases; the on_error handler's return value is passed through as-is, so it is not an Array. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
KaanOzkan
approved these changes
Sep 10, 2026
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type of Change
Changes
Alba ships no signatures, so tapioca emits every
Alba::Resource::ClassMethodsDSL macro sig-less. This adds signatures for the class-level macros used to define a resource. Every parameter list matches the one tapioca generates; every type is taken from the method body and its YARD doc.attribute/attributes—nameisString/Symbol,if:isSymbolorProc(Alba::ConditionalAttribute#condition_passes?branches on exactly those two), extra keywords are the untypedname => typepairs handed toAlba::TypedAttribute.associationand its aliasesone,many,has_one,has_many— types taken from the YARD@paramtags onassociation, which the aliases share;resource:/serializer:accept a resource class, aString, or aProc.nested_attribute/nested,trait— block isclass_eval'd, so it is bound to an untyped self and returns nothing useful.on_error—handleris one of:raise,:ignore,:nullify; the block is called ason_error.call(error, obj, key, attribute, klass)and its[key, value]return is destructured, henceT::Array[T.untyped].on_nil— called asinstance_exec(obj, key, attribute, &nil_handler).meta,layout,helper,collection_key,root_key,root_key!,root_key_for_collection,transform_keys,prefer_object_method!,prefer_resource_method!— direct reads of the assignments in each body.Two notes:
attribute(and ontraitandnested_attribute) is declared non-nilable. It is syntactically optional, but all three raiseArgumentErrorimmediately when it is absent, so a call without a block can only ever fail at runtime.transform_keys!is left unannotated: it returns the anonymousdupof the resource class, is marked experimental in the source, and I could not type it honestly.Instance methods (
serialize,as_json,serializable_hash) are deliberately left out of this first pass —serializable_hashreturns aHashor anArraydepending on whether the object is a collection, and a union return there would tighten code that type-checks today.bundle exec repo check --gem --ref upstream/mainpasses locally on all five checks (index, rubocop, rubygems, runtime, static).