Sorbet: Expected T::Array[X], got T::Array[X]

Created on 26 Mar 2020  路  4Comments  路  Source: sorbet/sorbet

I think we can improve this error message.

Input

# app/models/department.rb
has_many :users

# another_file.rb
sig { returns(T::Array[::User]) }
def users
  @_users ||= @department.users # add `to_a` here to fix
end

I assume it's not possible to do a sorbet.run because (I assume) reproduction requires rails.

Observed output

TypeError:
  Return value: Expected type T::Array[User], got T::Array[User]

Expected behavior

I'm not sure. I just know that the error "Expected X, got X" is not good.

Versions

bundle | grep sorb
Using sorbet-runtime 0.5.5469
Using sorbet-static 0.5.5469 (universal-darwin-19)
Using sorbet 0.5.5469
Using sorbet-coerce 0.2.4
Using sorbet-progress 0.3.0
Using sorbet-rails 0.6.1
bundle | grep ' rails '
Using rails 6.0.2.2
bug unconfirmed

All 4 comments

I can confirm that this is an error message that tripped many developers up at Shopify as well. I think we can remove the unconfirmed flag. I guess can create a test case to replicate it without needing Rails, by next week.

This happens when the underlying issue is an array-like object but is not actually an array (e.g. active record relation). You can fix this by declaring the type T::Enumerable[X] instead of T::Array[X]

Just stumbled across this today as well. What seems to fix it for me is changing:

sig { params(studies: T::Array[ReviewStudy], status: String).void }

To:

sig { params(studies: ReviewStudy::RelationType, status: String).void }

Where RelationType seems like it's defined by sorbet-rails as:

RelationType = T.type_alias { T.any(ReviewStudy::ActiveRecord_Relation, ReviewStudy::ActiveRecord_Associations_CollectionProxy, ReviewStudy::ActiveRecord_AssociationRelation) }

jez closed this in #3358

Thanks @paracycle and @jez !

Was this page helpful?
0 / 5 - 0 ratings