class T::Types::FixedArray
in the list.
Takes a list of types. Validates each item in an array using the type in the same position
def build_type
def build_type types nil end
def describe_obj(obj)
"Expected [String, Symbol], got Array".
instead of
"Expected [String, Symbol], got [String, String]"
This gives us better errors, e.g.:
def describe_obj(obj) if obj.is_a?(Array) if obj.length == types.length item_classes = obj.map(&:class).join(', ') "type [#{item_classes}]" else "array of size #{obj.length}" end else super end end
def initialize(types)
def initialize(types) @inner_types = types end
def name
def name "[#{types.join(', ')}]" end
def recursively_valid?(obj)
def recursively_valid?(obj) if obj.is_a?(Array) && obj.length == types.length i = 0 while i < types.length if !types[i].recursively_valid?(obj[i]) return false end i += 1 end true else false end end
def subtype_of_single?(other)
def subtype_of_single?(other) ther ixedArray operly speaking, covariance here is unsound since arrays n be mutated, but sorbet implements covariant tuples for se of adoption. s.size == other.types.size && types.zip(other.types).all? do |t1, t2| .subtype_of?(t2) ypedArray rning: covariant arrays e1, value2, *values_rest = types e_type = if !value2.nil? :Types::Union::Private::Pool.union_of_types(value1, value2, values_rest) f value1.nil? untyped lue1 ypes::TypedArray.new(value_type).subtype_of?(other) e
def types
def types @types ||= @inner_types.map {|type| T::Utils.coerce(type)} end
def valid?(obj)
def valid?(obj) if obj.is_a?(Array) && obj.length == types.length i = 0 while i < types.length if !types[i].valid?(obj[i]) return false end i += 1 end true else false end end