# Using TypeScript

Superstruct is built with TypeScript, and is designed to integrate seamlessly with its guards and assertions. Which means that if you're using TypeScript too you'll get compile-time typings for your data.

> 🤖 Warning: You must enable TypeScript's [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks) option in your `tsconfig.json` for Superstruct to work properly with "optional" types. Note that `strictNullChecks` is disabled by default. If you enable `strict`, `strictNullChecks` will automatically be enabled.

## Narrowing Types

Whenever you use the `is` or `assert` helpers in Superstruct, TypeScript will infer information about your data and give you type safety. For example:

```ts
import { is, number, object, string } from 'superstruct'

const User = object({
  id: number(),
  email: string(),
  name: string(),
})

if (is(data, User)) {
  // In this block TypeScript knows the shape of `data` is guaranteed to match
  // the `User` struct, so you can access properties like `data.name`.
}
```

Inside that `if` block you can safely access the `User` properties `id`, `name` and `email` because TypeScript knows that the data already passed validation.

The same for goes assertions:

```ts
assert(data, User)
// After this point TypeScript knows that data is valid too!
```

This makes it a lot easier to deal with inputs because you don't need to manually guard and refine their types.

## Describing Types

You can ensure that you're properly describing your existing TypeScript types with Superstruct by using the `Describe` utility. For example:

```ts
type User = {
  id: number
  name: string
}

const User: Describe<User> = object({
  id: string(), // This mistake will fail to pass type checking!
  name: string(),
})
```

In this case, the incorrectly defined `id` property will cause TypeScript's compilation checks to throw an error. This way your compile-time and run-time validations are never out of sync.

## Inferring Types

You can also do the reverse and infer a TypeScript type using an existing Superstruct struct with the `Infer` utility. For example:

```ts
import { Infer, number, object, string } from 'superstruct'

const User = object({
  id: number(),
  email: string(),
  name: string(),
})

type User = Infer<typeof User>
```

The `User` type above is the same as if you'd defined it by hand:

```ts
type User = {
  id: number
  email: string
  name: string
}
```

This saves you from having to duplicate definitions.

> 🤖 Notice that in each of the cases above, the `User` type and the `User` struct have the same name! This is handy for importing them elsewhere in the codebase at the same time.


---

# 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/06-using-typescript.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.
