FieldCodec
FieldCodec describes how a single URL field maps to a business value. It is the smallest unit in Decurl's codec layer: Search Fields, URLSearchParams codecs, and React Router hooks all reuse the same field codec.
The core field of FieldCodec is decode. It decides how raw URL strings become business values, and it also determines the value type TypeScript can infer. The other fields are not another parsing system; they add URL key, write-back, default value, and equality semantics at specific moments.
Minimal Definition
decode is the only required field, and it can be a plain function. The smallest definition does not even need field(...): as long as the object satisfies the FieldCodec shape, it can be used by Search Fields and hooks.
In real code, field(...) is still recommended to freeze the codec type. It lets TypeScript check earlier whether mode, decode input, defaultValue, and encode match, and it avoids unnecessary widening when object literals are composed later.
Without defaultValue, the decoded field may be undefined; with defaultValue, the decoded field always has a value.
@guanriyue/decurl/decode provides composable helpers. Using them is not required by FieldCodec. They only reduce repeated code and make common parsing rules easier to read.
Property Overview
Conceptually, a field codec can be understood as:
The real type is a more precise union based on mode, whether defaultValue exists, and the decode output type, which gives better type inference.
Read Timing
The difference between single and multi is the shape of the raw input passed to decode. A single field reads one URL value and decode receives string; a multi field reads all values with the same key and decode receives string[].
defaultValue is the fallback when a field cannot obtain a valid business value from the URL. When URLSearchParams does not contain the key, Decurl directly applies defaultValue and does not execute decode. When the key exists but decode returns null / undefined, Decurl also uses defaultValue. If decode throws, the expected behavior is also to fall back to defaultValue.
Most fields do not need custom encode or eq. Use encode only when values such as Date, objects, compressed strings, or special array formats need a custom write-back format. Use eq only when values such as objects, Date, or unordered arrays need business-level equality.
TypeScript
Type Inference
defaultValue cannot be null or undefined. This restriction guarantees the type promise that "a field with a default value always has a business value".
Literal objects can also be inferred, but field(...) is recommended to freeze the codec type. That lets TypeScript check each field's mode, default value, and decode input shape earlier, and avoids unnecessary type widening during later composition.
Hook Inference
useSearchValue reads a single named field codec. Usually it comes from the return value of defineFields.
useSearchValues reads a group of field codecs. The Search Fields below cover single optional, multi optional, single required, and multi required fields.