class T::Types::FixedHash
in the list.
Takes a hash of types. Validates each item in an hash using the type in the same position
def describe_obj(obj)
"Expected {a: String}, got Hash".
instead of
"Expected {a: String}, got {a: TrueClass}"
This gives us better errors, e.g.:
def describe_obj(obj) if obj.is_a?(Hash) "type {#{obj.map {|(k, v)| "#{k}: #{v.class}"}.join(', ')}}" else super end end
def initialize(types)
def initialize(types) @types = types.transform_values {|v| T::Utils.coerce(v)} end
def name
def name "{#{@types.map {|(k, v)| "#{k}: #{v}"}.join(', ')}}" end
def recursively_valid?(obj)
def recursively_valid?(obj) return false unless obj.is_a?(Hash) return false if @types.any? {|key, type| !type.recursively_valid?(obj[key])} return false if obj.any? {|key, _| !@types[key]} true end
def subtype_of_single?(other)
def subtype_of_single?(other) ther ixedHash ing `subtype_of?` here instead of == would be unsound es == other.types e
def valid?(obj)
def valid?(obj) return false unless obj.is_a?(Hash) return false if @types.any? {|key, type| !type.valid?(obj[key])} return false if obj.any? {|key, _| !@types[key]} true end