# Refining Validation

There are some cases where you want to create a validation that is more fine-grained than a "type". For example, you might want not just a `string`, but a specific format of string. Or not just a `User`, but a user that is also an administrator.

For these situations, you can use "refinements". Refinements allow you to create a new struct that is derived from an existing struct with an extra bit of validation layered on top.

## Built-in Refinements

Superstruct has several [built-in refinements](/api-reference/refinements.md) for common use cases. For example, a common one is ensuring that a string matches a specific regular expression pattern:

```ts
import { assert, pattern, string } from 'superstruct'

const Section = pattern(string(), /\d+(\.\d+/)?/)

assert('2', Section) // passes
assert('2.1', Section) // passes
assert('string', Section) // throws!
```

Or maybe that a string (or array, number, etc.) has a specific size:

```ts
import { assert, size, string } from 'superstruct'

const Name = size(string(), 1, 100)

assert('Alex', Name) // passes
assert('', Name) // throws!
```

Another common use case is validating nonnegative integers (like indexes in an array) using the built-in `min` helper:

```ts
import { assert, min, integer } from 'superstruct'

const Index = min(integer(), 0)

assert(42, Index) // passes
assert(0, Index) // passes
assert(3.14, Index) // throws!
assert(-1, Index) // throws!
```

These refinements don't change the inferred type of the data, but they do ensure that a slightly stricter validation is enforced at runtime.

## Custom Refinements

You can also write your own custom refinements for more domain-specific use cases. For example, for a specific kind of string:

```ts
import { refine, string } from 'superstruct'

const MyString = refine(string(), 'MyString', (value) => {
  return value.startsWith('The') && value.length > 20
})
```

Now the `MyString` will only validate strings that begin with "The" and are longer than 20 characters.

And whenever an error is thrown from the refinements, the `error.refinement` property will tell you which refinement was the cause.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.superstructjs.org/guides/04-refining-validation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
