# `Ash.Info.Manifest.ArgumentSignature`
[🔗](https://github.com/ash-project/ash/blob/v3.25.2/lib/ash/info/manifest/argument_signature.ex#L5)

Normalized argument signature for an operator, function, or custom expression.

One signature represents one accepted argument shape. The `args` list is the
ordered list of arg specs; each arg spec has a `kind`:

  * `:concrete` — a specific type module in `type_ref`.
  * `:same` — same type as the field being filtered (or the first arg).
  * `:any` — any type accepted.
  * `:array` — an array whose inner element spec is in `of`.
  * `:ref` — fallback for shapes we don't structurally model yet.

Use `from_ash_signature/1` to normalize the raw shape returned by an Ash
operator's `types/0` or a function's `args/0` callback. Short-name atoms
like `:string` are resolved through `Ash.Type.get_type/1` so that the
resulting `type_ref` is always the canonical type module — consumers never
see short-name aliases.

# `arg_spec`

```elixir
@type arg_spec() :: %{
  :kind =&gt; :concrete | :same | :any | :array | :ref,
  :type_ref =&gt; module() | nil,
  :constraints =&gt; keyword(),
  optional(:of) =&gt; arg_spec()
}
```

# `t`

```elixir
@type t() :: %Ash.Info.Manifest.ArgumentSignature{args: [arg_spec()], custom: map()}
```

# `from_ash_signature`

```elixir
@spec from_ash_signature(term()) :: t()
```

Normalize a raw signature from an Ash operator/function/custom expression callback.

Accepts:
- A list of arg specs (one explicit signature): `[:string, :string]`
- A bare sentinel atom (`:same` or `:any`) treated as a one-arg signature.

# `normalize_arg`

```elixir
@spec normalize_arg(term()) :: arg_spec()
```

Normalize a single arg spec entry.

---

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