Custom Types
There are a bunch of helpers for building your own types based on existing classes and values. These helpers are automatically defined if you're imported types in a module.
Types.Instance
Types.Instance
builds a type that checks if a value has the given class.
range_type = Types.Instance(Range)
range_type[1..2] # => 1..2
Types.Value
Types.Value
builds a type that checks a value for equality (using ==
).
valid = Types.Value('valid')
valid['valid'] # => 'valid'
valid['invalid']
# => Dry::Types::ConstraintError: "invalid" violates constraints (eql?("valid", "invalid") failed)
Types.Constant
Types.Constant
builds a type that checks a value for identity (using equal?
).
valid = Types.Constant(:valid)
valid[:valid] # => :valid
valid[:invalid]
# => Dry::Types::ConstraintError: :invalid violates constraints (is?(:valid, :invalid) failed)
Types.Constructor
Types.Constructor
builds a new constructor type for the given class. By default uses the new
method as a constructor.
user_type = Types.Constructor(User)
# It is equivalent to User.new(name: 'John')
user_type[name: 'John']
# Using a method User.build
user_type = Types.Constructor(User, &:build)
# Using a block
user_type = Types.Constructor(User) { |values| User.new(values) }
Types.Nominal
Types.Nominal
wraps the given class with a simple definition without any behavior attached.
int = Types.Nominal(Integer)
int[1] # => 1
# The type doesn't have any checks
int['one'] # => 'one'
Types.Hash
Types.Hash
builds a new hash schema.
# In the full form
Types::Hash.schema(name: Types::String, age: Types::Coercible::Integer)
# Using Types.Hash()
Types.Hash(:permissive, name: Types::String, age: Types::Coercible::Integer)
Types.Array
Types.Array
is a shortcut for Types::Array.of
ListOfStrings = Types.Array(Types::String)
Types.Interface
Types.Interface
builds a type that checks a value responds to given methods.
Callable = Types.Interface(:call)
Contact = Types.Interface(:name, :phone)