(Note that this isn't reproducible on sorbet.run, it's only reproducible with a local copy of Sorbet as far as I can tell)
I was hoping I could use the Typed Structs feature to create a method signature where one of the parameters is an options
hash, but this doesn't work:
# typed: true
require 'sorbet-runtime'
extend T::Sig
class OptionsStruct < T::Struct
prop :x, Integer, default: 1
end
sig { params(options: OptionsStruct).void }
def method(options)
puts options.x
end
# This works
method(OptionsStruct.new({x: 2}))
# This causes the typechecker to throw.
method({x: 2})
Essentially, when you typecheck this file it complains about passing a hash in, when a Struct is expected. My question is: how can I define a valid signature for a hash that has specific parameters? Structs clearly aren't working here. While I haven't tried Shapes, according to the docs they're very limited, so I'd prefer not to use them if possible.
The documentation on generics mentions Hashes but seems to suggest they can only be used if the hash's keys and values are all of the same types (e.g. Hash<Symbol, String>
requires that all keys be Symbols and all values be Strings), and doesn't provide any way (as far as I know) to define a hash with specific keys.
Thanks!
Hash
technically works in the signature, but then when you useoptions.x
in the method it saysx
isn't defined on the Hash. – Sekyereoptions.x
isn't a valid accessor for a hash... whoops. It should beoptions[:x]
. – Sekyere