---
title: 型注釈
description: 必要な SQL にだけ型を追加します。注釈は前提を検証し、結果を変えることはありません。
species: concept
---

# 型注釈

typesql は任意で型を付けられる SQL です。列が null にならない、数値が `decimal(28,2)` に収まる、JSON に `plan` フィールドがあるなど、前提に依存する箇所に注釈を付けます。検証器はクエリの実行前と、その下にあるスキーマが変わるたびに、レイクの実際のスキーマに照らして前提を検証します。

```typesql check=p1
select
  id,
  amount satisfies integer!,
  metadata::json<{plan: string}> ->> 'plan' as plan
from titan.stripe.charges
```

## 保証

注釈はクエリの結果を変えません。typesql ドキュメントからすべての注釈を取り除くと、同じ行、同じ値、すべてが同じ結果になる通常の SQL が残ります。これは慣習ではなく構造上の保証です。型は検証後に消去され、どの実行経路からも読み取れません。

そのため、一括移行を決める必要はありません。1 つのクエリの 1 つの式だけに注釈を付けても、モデル全体に型を付けてもかまいません。「通常の SQL」から「完全な型付き SQL」まで、どの段階でも動作します。

## `satisfies`：式を検証する

式を記述できる場所なら、どこでも `expr satisfies type` を使えます。

```typesql check=p1
select
  round(sum(amount) / 100.0, 2) satisfies decimal(38,2) as gross_volume
from titan.stripe.charges
where not _deleted
```

スキーマ変更によりその式が decimal 以外になった場合、ダッシュボードが黙って不正な結果を表示する前に、モデルの検証が失敗し、該当範囲を示す診断を返します。すべての診断に安定した `TS` コード、位置、修正方法を示す `help:` 行が含まれます。

`satisfies` はキャストではありません。`amount::string` は値を変換し、`amount satisfies string` は事実を表明して、正しくなければ検証を失敗させます。データを変えるには `::`、前提の変化を検出するには `satisfies` を使います。

## 非 null：`!` と絞り込み

`string!` は「文字列であり、null にはならない」という意味です。検証器はクエリのロジックが null 許容性に与える影響を理解するため、次の例は検証を通過します。

```typesql check=p1
select email satisfies string!
from titan.stripe.customers
where email is not null
```

`where` 句を取り除くと検証に失敗します。スキーマでは `email` が null を許容し、クエリ内で null を除外していないためです。逆も同様で、入力時に非 null の列でも `left join` の外側では null を許容するようになり、検証器はその変化も追跡します。検証はスキーマの定義だけでなく、クエリの動作を反映します。

## 型付き CTE ヘッダー

CTE ヘッダーで列の型を宣言すると、クエリの各段階の境界を検証可能な契約にできます。

```typesql check=p1
with monthly(month: date!, gross_volume: decimal(38,2)) as (
  select
    date_trunc('month', created_at)::date,
    round(sum(amount) / 100.0, 2)
  from titan.stripe.charges
  where not _deleted
  group by 1
)
select * from monthly where gross_volume > 250000
```

本体をヘッダーに照らして検証し、`monthly` より下流では宣言した型を使います。型を消去するとヘッダーは `with monthly(month, gross_volume) as (…)` になり、通常の SQL として実行します。

## 型付き JSON

JSON 列の構造を指定すると、内部へのアクセスを推測に頼らずに済みます。

```typesql check=p1
select
  metadata::json<{plan: string, seats: integer}> as meta,
  meta ->> 'plan' as plan
from titan.stripe.charges
```

`meta ->> 'paln'` のような入力ミスは検証エラーになります。後になって別のダッシュボードで null の列として見つかることはありません。

## エディターで使う

クエリエディターは入力中に同じ検証器を実行します。式にカーソルを重ねると推論した型が表示されます。インレイヒントは検証器がすでに把握している型を示し、クリックすると実際の `satisfies` 注釈としてクエリに挿入します。1 クリックずつ型を追加できます。クイックフィックスも診断と同じ修正を適用します。

## 次に読むページ

- [モデルの作成](/docs/models/authoring)では、モデルを実行のたびにレイクに照らして検証します。
`-- lint:` ヘッダーで、実行を止める診断を調整できます。
- 型システムのページでは、スカラー、`decimal(p,s)`、リスト、
構造体、テーブルの型、および `_synced_at` などのシステム列の型付けを含む、文法全体を説明しています。
