Search code examples
rubysorbet

Sorbet variable array length


I'm just starting to play around with the sorbet gem. I have a method that expects and returns an array of objects. The thing is, the length of the array is varied. How can I type check the method? I keep getting Expected type [Object], got array of size 2

Here's my method

sig { params(foo: Array[Object]).returns(Array[Object]) }
def bar(foo)
  # code to modify some of the attributes
end

Solution

  • tl;dr You have a syntax error. Use T::Array[Object] (not Array[Object]).

    You're using incorrect type syntax for arrays:

    # typed: strict
    
    extend T::Sig
    
    sig { params(foo: Array[Object]).returns(Array[Object]) }
    def bar(foo)
      # code to modify some of the attributes
    end
    

    → View on sorbet.run

    The errors show:

    editor.rb:5: Use T::Array[...], not Array[...] to declare a typed Array https://srb.help/5026
         5 |sig { params(foo: Array[Object]).returns(Array[Object]) }
                                                     ^^^^^^^^^^^^^
      Note:
        Array[...] will raise at runtime because this generic was defined in the standard library
      Autocorrect: Use `-a` to autocorrect
        editor.rb:5: Replace with T::Array
         5 |sig { params(foo: Array[Object]).returns(Array[Object]) }
                                                     ^^^^^
    
    editor.rb:5: Use T::Array[...], not Array[...] to declare a typed Array https://srb.help/5026
         5 |sig { params(foo: Array[Object]).returns(Array[Object]) }
                              ^^^^^^^^^^^^^
      Note:
        Array[...] will raise at runtime because this generic was defined in the standard library
      Autocorrect: Use `-a` to autocorrect
        editor.rb:5: Replace with T::Array
         5 |sig { params(foo: Array[Object]).returns(Array[Object]) }
                              ^^^^^
    Errors: 2
    

    Why is it like this?

    The [] method on Array has special meaning, but Sorbet uses [] for generic type arguments. To get around that, Sorbet uses the T:: namespace for certain generic classes in the standard library:

    https://sorbet.org/docs/stdlib-generics

    What's happening in your case is that this code:

    Array[Object]
    

    is equivalent to having written this:

    [Object]
    

    (i.e., "make an array of length one containing the value Object"). [Object] in Sorbet happens to be the way to express a 1-tuple.