カテゴリ: Ruby 更新日: 2026/02/22

RBSでRubyに型を付けよう!typeprofとsteepで静的型チェック入門

RBSで型を付ける:typeprof/steepの導入と静的型チェックの基本
RBSで型を付ける:typeprof/steepの導入と静的型チェックの基本

先生と生徒の会話形式で理解しよう

生徒

「先生、Rubyって“動的型付け”の言語って聞きましたけど、型っていらないんですか?」

先生

「とても良い質問です。Rubyは型を自動で判断してくれるので“型を宣言する必要がない”のが特徴なんです。ただし、大きなプログラムになると『この変数はどんな型?』って分かりにくくなることがあります。」

生徒

「なるほど…。じゃあ、型を明示できたら便利そうですね!」

先生

「その通り!そこで登場するのがRBS(Ruby Signature)typeprof、そしてsteepという仕組みなんです。今日はそれを一緒に学んでいきましょう!」

1. RBSとは?Rubyに“型の設計図”を与える仕組み

1. RBSとは?Rubyに“型の設計図”を与える仕組み
1. RBSとは?Rubyに“型の設計図”を与える仕組み

Rubyはとても自由な言語で、変数にあとから別の型の値を代入してもエラーになりません。これを動的型付けといいます。最初はとても書きやすく感じますが、ファイル数やクラスが増えてくると、「ここには本当はどんな値が入る想定なんだろう?」と迷子になりがちです。その結果、意図しない型のデータを渡してしまい、思わぬバグにつながることがあります。

そこで登場するのがRBS(Ruby Signature)です。RBSはRubyコードとは別に用意する「型の設計図ファイル」で、「このクラスのこのメソッドは、こういう型のデータを受け取って、こういう型のデータを返すよ」と人間とツールの両方に教えてくれます。RBSファイル(拡張子は.rbs)はあくまで設計図なので、そのまま実行されることはありませんが、後で行う静的型チェックの土台になります。

まずはイメージしやすいように、Rubyのコード例を見てみましょう。名前を受け取ってあいさつ文を返すだけの、とてもシンプルなクラスです。


class User
  def initialize(name)
    @name = name
  end

  def greet
    "こんにちは、#{@name}さん!"
  end
end

このクラスに対してRBSファイルを作ると、次のように書けます。


class User
  def initialize: (String) -> void
  def greet: () -> String
end

ここで「(String) -> void」というのは、「initializeメソッドは、String型(文字列)の値を1つ受け取って、呼び出し元には何も返さない(void)」という意味です。そして「() -> String」は「greetメソッドは引数を受け取らず、その代わりにString型(文字列)を必ず返す」ということを表しています。

実際のRubyコードだけを眺めていると、「nameには文字列が入る想定なのか?それとも別のオブジェクトも来るのか?」と読み手によって解釈が分かれることがあります。しかしRBSで型をはっきり書いておくと、「このクラスは文字列の名前を前提に設計されているんだな」とひと目で分かります。プログラミング未経験の人でも、「この箱にはこういう種類の値だけを入れてください」というルールを書いたメモだと思えば、RBSが担っている役割をイメージしやすいはずです。

2. typeprofを使ってRBSを自動生成してみよう

2. typeprofを使ってRBSを自動生成してみよう
2. typeprofを使ってRBSを自動生成してみよう

「RBSファイルって自分で全部書くの?」と感じる人は多いと思います。実際、最初から細かい型情報を手作業で書くのは大変です。そこで心強い味方になるのが、Rubyに標準搭載されているtypeprofというツールです。typeprofはRubyのコードを読み取り、「このメソッドはこんな値を受け取って、こんな値を返しているんじゃないかな?」と推測し、RBSファイルの元となる情報を自動で作成してくれます。

イメージとしては、コードの“性格診断”をしてくれるようなもので、自分が書いたコードの型をざっくり把握したいときにとても便利です。初心者でも難しい設定なしで使えるので、まずは気軽に試してみるのがおすすめです。

例として、前の章で作ったuser.rbを typeprof に渡してみましょう。ターミナル(黒い画面)に次のように入力します。


typeprof user.rb

すると、typeprof がコードを分析して、次のような推論結果を表示します。


# Classes
class User
  def initialize: (String) -> void
  def greet: () -> String
end

この結果は、「initializeは文字列を受け取って何も返さない」「greetは引数なしで文字列を返す」という推測を示しています。つまり、typeprofは Ruby のコードを読み解き、型のヒントとなる情報を自動で作ってくれる便利なツールなのです。

プログラミングに慣れていない人でも、「自分のコードがどんな型として扱われているのか」を目で見て確認できるのは大きな安心材料になります。手作業でRBSを書く前に、まずはtypeprofで雛形を作ってみると理解がぐっと深まります。

3. steepで静的型チェックを行う

3. steepで静的型チェックを行う
3. steepで静的型チェックを行う

steep(スティープ)は、RBSファイルを使って実際のRubyコードと照らし合わせながら「型の不整合がないか」をチェックしてくれるツールです。いわば、“Rubyコードのスペルチェック”のようなものです。

まず、steepをインストールしましょう。ターミナルで次を実行します。


gem install steep

次にプロジェクトのルートで初期設定を行います。


steep init

これでSteepfileという設定ファイルが作られます。steepはこのファイルを読み込み、どのRubyファイルとRBSファイルをチェックするかを判断します。

設定ができたら、次のコマンドで型チェックを実行します。


steep check

たとえば、Ruby側で次のようなミスをしていた場合を見てみましょう。


class User
  def initialize(name)
    @name = name
  end

  def greet
    123  # 本当は文字列を返すべきなのに数字を返している!
  end
end

この状態でsteep checkを実行すると、次のようなエラーが出ます。


# Type error: Expected String but got Integer

このように、Rubyの柔軟さを保ちながらも、型のミスを事前に発見することができます。特に大規模なアプリ開発では非常に役立ちます。

4. typeprofとsteepの違いを整理しよう

4. typeprofとsteepの違いを整理しよう
4. typeprofとsteepの違いを整理しよう

ここで、二つのツールの役割を整理してみましょう。

  • typeprof:既存のRubyコードから型を推測して、RBSファイルを自動生成するツール。
  • steep:RBSファイルを使って、Rubyコードの型を静的にチェックするツール。

つまり、typeprofで型情報を作り、steepで確認するという流れになります。

この2つを組み合わせることで、「Rubyは動的型付けだから型がわからない」という不安を大きく減らすことができます。

5. RBSを使うと何がうれしいの?

5. RBSを使うと何がうれしいの?
5. RBSを使うと何がうれしいの?

RBSを使うことで、以下のようなメリットがあります。

  • コードを読むときに「このメソッドは何を返すか」がすぐに分かる。
  • チーム開発で他の人が作ったコードでも安心して使える。
  • 型エラーを事前に発見できるため、バグの減少につながる。

特に、Ruby on Railsのような大きなフレームワークを使う場合や、他人と共同でプログラムを作る場合に、RBSとsteepは非常に心強い味方になります。

6. Rubyにも型の世界を取り入れよう

6. Rubyにも型の世界を取り入れよう
6. Rubyにも型の世界を取り入れよう

Rubyは柔軟で使いやすい言語ですが、RBSやsteepを使うことで、静的型付け言語のような「安心感」も手に入ります。特にこれからプログラムを長く続けていく人にとって、RBSの考え方は大切な基礎になります。

次のステップとして、自分のRubyプロジェクトで実際にtypeprofsteepを動かしてみましょう。小さなスクリプトでも、型のチェックができるとぐっと理解が深まります。

まとめ

まとめ
まとめ

今回の学習では、Rubyの動的型付けという特徴をふまえながら、RBSやtypeprof、そしてsteepを使った静的型チェックの基本的な流れを丁寧に振り返りました。Rubyはコードを書くときに型を宣言しなくても動作する柔軟さが魅力ですが、プロジェクトが大規模化すると「このメソッドはどんな引数を受け取るのか」「返り値は何なのか」といった情報が不透明になり、理解や保守が難しくなります。そこで登場するのがRBSという“型の設計図”であり、Rubyコードと併せて読み解くことで、プログラム全体の構造がより明確になります。とくにクラスやメソッドの役割を整理したいとき、RBSで型情報を外部化することは大きな助けになります。さらにtypeprofを活用すれば、既存のRubyコードから自動的に型を推論し、RBSファイルを生成することができ、手作業で型を書く手間を大幅に軽減できます。 型情報がそろったら、steepを使った静的型チェックによって実際のRubyコードとRBSを突き合わせ、型の不一致や設計上の矛盾を早期に発見できます。開発の初期段階でこのチェックを取り入れることで、潜在的なエラーを未然に防ぎ、長期的な品質向上につながります。とくにチーム開発では、RBSが共通の認識となり、メンバー同士が安心してコードを読み書きできるという大きな利点があります。静的型チェックを導入するということは、単に型を厳格にするだけではなく、コード全体の見通しや再利用性を高めるための重要な手段でもあります。 ここであらためて、RBS・typeprof・steepそれぞれの役割をふり返ってみましょう。RBSは明示的に型を設計し、クラスやメソッドの構造を整理する“型の辞書”のような存在です。typeprofはRubyコードから推論してその辞書を自動生成するアシスタントのようなツール。そしてsteepは辞書と実際のコードに矛盾がないかをチェックする検査官のような役割です。この三つをセットで使うことで、Rubyでも静的型言語に近い安心感を得ながら、動的型付けの自由さはそのまま保つという、バランスの取れた開発環境が整います。 以下は、まとめとして示す簡単なサンプルプログラムです。記事内で扱ったclassやタグと同じような構造を用いています。

サンプル(RubyコードとRBS)


class Order
  def initialize(id, total)
    @id = id
    @total = total
  end

  def info
    "注文ID: #{@id} 合計金額: #{@total}"
  end
end

class Order
  def initialize: (Integer, Integer) -> void
  def info: () -> String
end

このようにRubyのコードとRBSを並べると、それぞれのメソッドが受け取る型や返す型が視覚的に理解しやすくなり、型の整合性に自信を持ちながらプログラムを書くことができます。特に業務アプリケーションや長期運用されるサービスでは、型情報が豊富であるほど安心してコードを引き継ぐことができます。動的型付け言語であるRubyでも、RBSを活用することで静的な側面を取り込み、コード品質の向上に大きく寄与できます。

先生と生徒の振り返り会話

生徒

「先生、今日の内容でRubyでも型を扱える理由がよくわかりました!動的型付けの自由さは残しつつ、RBSで型を明確にすることで安心感が増すんですね。」

先生

「その通りです。Rubyは柔軟で書きやすい言語ですが、大きな開発では型情報があるだけで理解がぐっと楽になります。RBSはあくまで“外側から型を付ける”仕組みなので、Rubyの書きやすさを損ないません。」

生徒

「そしてtypeprofで自動生成できるのが助かりますね。わざわざ全部を書かなくても推論してくれるのが便利です。」

先生

「そのとおり。さらにsteepを組み合わせれば、実際のコードとRBSが矛盾していないかを簡単にチェックできます。バグの早期発見にもつながります。」

生徒

「なるほど、三つを合わせて使うことでRubyでも型安全な開発ができるわけですね!」

先生

「そうです。型を味方につけることで、Rubyの開発はもっと強力で読みやすく、保守しやすくなりますよ。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Rubyは動的型付け言語なのに、RBSで型を付ける意味はありますか?

Rubyは動的型付けで型の宣言が不要ですが、RBSを使うことで「この変数は何の型なのか?」が明確になり、大規模開発やチーム開発での可読性や保守性が大幅に向上します。
関連記事:
カテゴリの一覧へ
新着記事
New1
Ruby
“すべてはオブジェクト”を体感!初心者向けRubyのオブジェクト指向入門【irbで学ぶ】
New2
Ruby
Rubyの標準入出力を完全ガイド!puts・print・pの違いとデバッグ活用法
New3
Ruby
Gemとは?RubyGemsとBundlerを初心者向けに完全解説!依存関係管理も図解でわかりやすく理解
New4
Ruby
Rubyの文字エンコーディング入門!UTF-8・マジックコメント・外部/内部エンコーディングを完全解説
人気記事
No.1
Java&Spring記事人気No1
Ruby
Rubyのreduceとinject入門!合計計算や集計を初心者向けに分かりやすく解説
No.2
Java&Spring記事人気No2
Ruby
Rubyの文字列エンコーディング完全ガイド!Encoding・force_encoding・encodeを初心者向け解説
No.3
Java&Spring記事人気No3
Ruby
Rubyの始め方ガイド:インストールから最初のHello Worldまで(Windows/Mac/Linux)
No.4
Java&Spring記事人気No4
データベース
PostgreSQLのWHERE句を徹底解説!初心者でもわかるSQLデータ抽出の基本
No.5
Java&Spring記事人気No5
Ruby
Rubyのfind/detect/find_indexを徹底解説!目的のデータを素早く探す方法
No.6
Java&Spring記事人気No6
Ruby
Rubyで比較演算子を完全解説!==・===・<=>・eql? の使い分け
No.7
Java&Spring記事人気No7
Ruby
Rubyのselect/reject/filterの使い方を完全解説!初心者向けの条件抽出レシピ
No.8
Java&Spring記事人気No8
データベース
PostgreSQLで順位付け!ROW_NUMBER関数の使い方を初心者向けに徹底解説