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 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 builds a type that checks a value for equality (using ==).

valid = Types.Value('valid')
valid['valid'] # => 'valid'
# => Dry::Types::ConstraintError: "invalid" violates constraints (eql?("valid", "invalid") failed)


Types.Constant builds a type that checks a value for identity (using equal?).

valid = Types.Constant(:valid)
valid[:valid] # => :valid
# => Dry::Types::ConstraintError: :invalid violates constraints (is?(:valid, :invalid) failed)


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 'John')
user_type[name: 'John']

# Using a method
user_type = Types.Constructor(User, &:build)

# Using a block
user_type = Types.Constructor(User) { |values| }


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 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 is a shortcut for Types::Array.of

ListOfStrings = Types.Array(Types::String)


Types.Interface builds a type that checks a value responds to given methods.

Callable = Types.Interface(:call)
Contact = Types.Interface(:name, :phone)

octocatEdit on GitHub