@@ -73,19 +73,19 @@ class Student
7373 include FrozenRecordAttributeMethods
7474
7575 module FrozenRecordAttributeMethods
76- sig { returns(String ) }
76+ sig { returns(T::untyped ) }
7777 def first_name; end
7878
7979 sig { returns(T::Boolean) }
8080 def first_name?; end
8181
82- sig { returns(Integer ) }
82+ sig { returns(T::untyped ) }
8383 def id; end
8484
8585 sig { returns(T::Boolean) }
8686 def id?; end
8787
88- sig { returns(String ) }
88+ sig { returns(T::untyped ) }
8989 def last_name; end
9090
9191 sig { returns(T::Boolean) }
@@ -101,13 +101,66 @@ def last_name?; end
101101 add_ruby_file ( "student.rb" , <<~RUBY )
102102 # typed: strong
103103
104+ class ArrayOfType < ActiveModel::Type::Value
105+ attr_reader :element_type
106+
107+ def initialize(element_type:)
108+ super()
109+ @element_type = element_type
110+ end
111+
112+ def type
113+ :array
114+ end
115+ end
116+
117+ class HashOfType < ActiveModel::Type::Value
118+ attr_reader :key_type
119+ attr_reader :value_type
120+
121+ def initialize(key_type:, value_type:)
122+ super()
123+ @key_type = key_type
124+ @value_type = value_type
125+ end
126+
127+ def type
128+ :hash
129+ end
130+ end
131+
132+ class SymbolType < ActiveModel::Type::Value
133+ def type
134+ :symbol
135+ end
136+ end
137+
138+ ActiveModel::Type.register(:array_of_type, ArrayOfType)
139+ ActiveModel::Type.register(:hash_of_type, HashOfType)
140+ ActiveModel::Type.register(:symbol, SymbolType)
141+
104142 class Student < FrozenRecord::Base
105- extend(T::Sig)
143+ extend T::Sig
144+ include ActiveModel::Attributes
145+
146+ # specifically missing the id field, should be untyped
147+ attribute :first_name, :string
148+ attribute :last_name, :string
149+ attribute :age, :integer
150+ attribute :location, :string
151+ attribute :is_cool_person, :boolean
152+ attribute :birth_date, :date
153+ attribute :updated_at, :time
154+ # custom attribute types
155+ attribute :favourite_foods, :array_of_type, element_type: :string
156+ attribute :skills, :hash_of_type, key_type: :symbol, value_type: :string
157+ # attribute with a default, shouldn't be nilable
158+ attribute :shirt_size, :symbol
106159
107160 self.base_path = __dir__
108-
109161 self.default_attributes = { shirt_size: :large }
110162
163+ # Explicit method, shouldn't be in the RBI output
111164 sig { params(grain: Symbol).returns(String) }
112165 def area(grain:)
113166 parts = location.split(',').map(&:strip)
@@ -161,67 +214,67 @@ class Student
161214 include FrozenRecordAttributeMethods
162215
163216 module FrozenRecordAttributeMethods
164- sig { returns(Integer) }
217+ sig { returns(T.nilable(:: Integer) ) }
165218 def age; end
166219
167220 sig { returns(T::Boolean) }
168221 def age?; end
169222
170- sig { returns(Date) }
223+ sig { returns(T.nilable(:: Date) ) }
171224 def birth_date; end
172225
173226 sig { returns(T::Boolean) }
174227 def birth_date?; end
175228
176- sig { returns(Array) }
229+ sig { returns(T.nilable(:: Array) ) }
177230 def favourite_foods; end
178231
179232 sig { returns(T::Boolean) }
180233 def favourite_foods?; end
181234
182- sig { returns(String) }
235+ sig { returns(T.nilable(:: String) ) }
183236 def first_name; end
184237
185238 sig { returns(T::Boolean) }
186239 def first_name?; end
187240
188- sig { returns(Integer ) }
241+ sig { returns(T.untyped ) }
189242 def id; end
190243
191244 sig { returns(T::Boolean) }
192245 def id?; end
193246
194- sig { returns(T::Boolean) }
247+ sig { returns(T.nilable(T ::Boolean) ) }
195248 def is_cool_person; end
196249
197250 sig { returns(T::Boolean) }
198251 def is_cool_person?; end
199252
200- sig { returns(String) }
253+ sig { returns(T.nilable(:: String) ) }
201254 def last_name; end
202255
203256 sig { returns(T::Boolean) }
204257 def last_name?; end
205258
206- sig { returns(String) }
259+ sig { returns(T.nilable(:: String) ) }
207260 def location; end
208261
209262 sig { returns(T::Boolean) }
210263 def location?; end
211264
212- sig { returns(Symbol) }
265+ sig { returns(:: Symbol) }
213266 def shirt_size; end
214267
215268 sig { returns(T::Boolean) }
216269 def shirt_size?; end
217270
218- sig { returns(Hash) }
271+ sig { returns(T.nilable(:: Hash) ) }
219272 def skills; end
220273
221274 sig { returns(T::Boolean) }
222275 def skills?; end
223276
224- sig { returns(Time ) }
277+ sig { returns(T.nilable(::DateTime) ) }
225278 def updated_at; end
226279
227280 sig { returns(T::Boolean) }
@@ -257,13 +310,13 @@ class Student
257310 extend GeneratedRelationMethods
258311
259312 module FrozenRecordAttributeMethods
260- sig { returns(String ) }
313+ sig { returns(T::untyped ) }
261314 def course; end
262315
263316 sig { returns(T::Boolean) }
264317 def course?; end
265318
266- sig { returns(Integer ) }
319+ sig { returns(T::untyped ) }
267320 def id; end
268321
269322 sig { returns(T::Boolean) }
0 commit comments