[Dry-Struct] How to create a nested struct in an optional array?

I’m trying to create an attrbute that is an optional array with a nested struct.
I’ve tried

attribute :someArray, Types::Array.of(
Dry::Schema.optional do
  attribute :someString, Types::String
attribute :someInteger, Types::Integer
).optional

But that results in an array of empty hashes. What is the correct way to do this?
Thank you for your help!

What part of this do you want to be optional? An array type allows itself to be empty unless you constrain it with min_size.

If you want the key itself to be optional, declare it with attribute?

attribute? :someArray, Types::Array.default { [] } do
  attribute :someString, Types::String
  attribute :someInteger, Types::Integer
end

I do not want the key to be optional, I want the value of the array to be optional. The value of the array can be nil or it can be an array of structs.

Explicitly passing nil is a little trickier, since it doesn’t seem to be compatible with inline nesting. But you can achieve that by decomposing the nested struct.

class Thing < Dry::Struct
  attribute :someString, Types::String
  attribute :someInteger, Types::Integer
end

class Test < Dry::Struct
  attribute :someArray, Types::Array.of(Thing).optional
end
[1] pry(main)> Test.new
Dry::Struct::Error: [Test.new] :someArray is missing in Hash input
[2] pry(main)> Test.new({ someArray: nil })
=> #<Test someArray=nil>
[3] pry(main)> Test.new({ someArray: [] })
=> #<Test someArray=[]>
[4] pry(main)> Test.new({ someArray: [{}] })
Dry::Struct::Error: [Thing.new] :someString is missing in Hash input
[5] pry(main)> Test.new({ someArray: [{ someString: 'foo', someInteger: 123 }] })
=> #<Test someArray=[#<Thing someString="foo" someInteger=123>]>