# `Ash.Type.NewType`
[🔗](https://github.com/ash-project/ash/blob/v3.23.1/lib/ash/type/new_type.ex#L5)

Allows defining a new type that is the combination of an existing type and custom constraints

A subtle difference between this type and its supertype (one that will almost certainly not matter
in any case) is that we use the `apply_constraints` logic of the underlying type in the same step
as `cast_input`. We do this because new types like these are, generally speaking, considering the constraint
application as part of the core type. Other types, if you simply do `Ash.Type.cast_input/3` you will not be
also applying their constraints.

## Options

- `:subtype_of` - The type that this new type is a subtype of.
- `:constraints` - The constraints that this new type uses for the underlying type.
- `:lazy_init?` - If true, the `init/1` function will be called at runtime instead of compile time.
  Allows for recursive types.

For Example:

```elixir
defmodule MyApp.Types.SSN do
  use Ash.Type.NewType, subtype_of: :string, constraints: [match: ~r/regex for ssn/]
end

defmodule MyApp.Types.Metadata do
  use Ash.Type.NewType, subtype_of: :union, constraints: [types: [
    foo: [...],
    bar: [...]
  ]]
end
```

# `t`

```elixir
@type t() :: module() | atom() | {:array, module() | atom()}
```

# `lazy_init?`

```elixir
@callback lazy_init?() :: boolean()
```

Whether or not the type is lazy initialized (so needs to be initialized when fetching constraints)

# `subtype_constraints`

```elixir
@callback subtype_constraints() :: Keyword.t()
```

Returns the underlying subtype constraints

# `subtype_of`

```elixir
@callback subtype_of() :: module() | atom()
```

Returns the type that the NewType is a subtype of.

# `type_constraints`

```elixir
@callback type_constraints(constraints :: Keyword.t(), subtype_constraints :: Keyword.t()) ::
  Keyword.t()
```

Returns the modified NewType constraints

# `constraints`

```elixir
@spec constraints(Ash.Type.t(), Keyword.t()) :: Keyword.t()
```

Returns the constraints schema.

# `new_type?`

```elixir
@spec new_type?(Ash.Type.t()) :: boolean()
```

Returns true if the corresponding type is an Ash.Type.NewType

# `subtype_of`

```elixir
@spec subtype_of(t()) :: Ash.Type.t()
```

Returns the type that the given newtype is a subtype of

---

*Consult [api-reference.md](api-reference.md) for complete listing*
