RubyエンジニアがTypeScriptをやってみた💡
はじめに
こんにちは!
スペースマーケットでバックエンドエンジニアをしている者です!
筆者は、今までRuby on Rails(以下、Rails)をメインでバックエンドの開発をしてきました。
もちろんスペースマーケットに入ってからも開発の多くはRailsで行っていたのですが、最近ではNestJSというNode.jsのフレームワークを使用した開発も増えてきました。
なので、現在はNestJSと、そのフレームワークで使用している言語であるTypeScriptを学習している真っ最中なのです。
ということで、今回は「RubyエンジニアがTypeScriptをやってみた」という内容で記事を書いていこうと思います!
普段Rubyを使っているエンジニアとして、TypeScriptの良いところや違和感を感じながら記事を書きましたので、筆者と同じくRubyからTypeScriptへ転換する方の参考になれば幸いです。
TypeScriptの勉強開始!!
それでは学習を開始していきます!
私はTypeScriptに以下の記事や書籍を参考に学習しました。
参考資料
速習TypeScript: altJSのデファクトスタンダートを素早く学ぶ!
こちらのネットの記事や書籍を読んでみて、興味深いことは多かったのですが、その中でも特に「印象に残ったところ」「重要そうなところ」をまとめてみました。
- TypeScriptはJavaScriptとは別物
- 共用型[Union型]が重要
- undefinedとnullの違いは戦争になる
ここからは、上記のトピックを順番に書いていきます。
TypeScriptはJavaScriptとは別物?
JavaScriptとTypeScriptは全くの別物というわけではなく、TypeScriptは、AltJSと呼ばれる「コンパイルするとJavaScriptに変換される言語」です。
なので、コンパイルをするとjsファイルが出来上がります。
なので、TypeScriptのファイルにJavaScriptを書いても問題ないらしいです(もっとも、それではTypeScriptの型システムの意味がありませんが、、)
そういえば、Railsもversion4だか5の頃に「CoffeeScript」とかいうAltJSが標準採用されてたっけ、、、
共用型[Union型]が重要(なんだと思う)
元来、型システムがないRubyを使う我々インタプリタ言語エンジニアは「んーと、、この変数は配列なんだっけ、、ハッシュなんだっけ、、」という風にいつもエラーになる不安を孕んだまま開発をしております。
# いつも頭を悩ませるところ
yamou_list = なんかs.map { |なんか| Nanka.find(1) }
yamou_list # あれ?この変数ってなんなの?ActiveRecord?配列?
ですが、TypeScriptになると型システムがあるので、全く悩む心配もないです!!
let data: string | boolean;
????
「 | 」で区切っているのは何者でしょうか!
どうやら位置的にプリミティブな型を複数定義しているのでしょうが、一体何者なのか初見では全く分かりません。
■ 共用型(Union Types)
→ 複数の型のどれかを表す型、型をパイプ( | )で区切ることで表現する
複数の型を使用する場合は、Union型を使うべき。
なるほど、型をパイプ( | )で区切っているものは、共用型というらしいです。
これで筆者の教養も一段と深みが増しました(この発言自体の教養が浅い)
const gqlRoom: RoomObjectType | null = await this.queryBus.execute(・・);
if (!gqlRoom) {
実際の会社のコードでも、上のようにをUnion型を定義していました。
上の場合は定数の型がRoomObjectType
でなかったときに意図的にnull
を出して、ifで例外処理を書いているのだと思われます(多分、、)
なので、こちらのUnion型、結構実務でも使用するケースがありそうです。
、、、きっと重要なんです、、、
undefinedとnullの違いは戦争になる?
undefinedとnullをどう使い分けたらいいかは大きな論争を呼ぶテーマです。
プログラマーの中には、undefinedだけを使うべきと言う人もいれば、nullを使うべきという人もいます。
また、undefinedとnullの意味合いの違いをしっかり理解して、使い分けるべきと主張する人もいます。
逆に、深く考えすぎずに使うというスタンスの人もいます。
というように、両者の使い分けは戦争(論争)を生むそうです。
そう、元来Rubyエンジニアは「nil(ニル)」を知っていたが、「null(ヌル)」という言葉すら交わすことは無かった。
だから、Javaを使うエンジニアと、とある掲示板の住民たちがよく使っていた「ぬるぽ」という言葉が分からず、彼らが盛り上がっている中で僕達は分かった振りすらできなかったんだ、、、
# やたらと語感が可愛いと筆者から定評がある「nil(ニル)」。「煮る」ではない。
@nantara_list = [1, 2, 3]
if @nantara_list[5].nil?
puts "「何たら」はありません"
else
puts "「何たら」があります!"
end
# 結果: 「何たら」はありません
===============
undefinedとnullは大きなくくりで「値がない」ことを意味する点は共通しています。
意味的な違いがあるとしたら、undefinedは「値が代入されていないため、値がない」、
nullは「代入すべき値が存在しないため、値がない」という微妙な違いです。
どうやらTypeScriptでは、Rubyで「nil」が発生するようなタイミングで発生するのが「undefined」で、「null」はエンジニアが意図的に組み込まない限り、発生しないようです。
(↑戦争が起こらぬ前に、もし認識の齟齬があったら教えてください、、(-人-))
この両者の使い分けは、チームの開発スタイルによって変わってくるようなので、この辺りは実戦で慣れていくしかなさそうですね。
Rubyと比較してみて所感
やはり、Rubyとの大きな違いは型システムがあることです。
筆者もまだまだ分からないことだらけで、「あれ?これは引数の型?戻り値の型?」という風に関数を書くだけでもかなりの体力を使いながら学習しています。
ですが、こうして時間を掛けて、より良いコードを書くためによく考えて実装していくのは、Rubyには無い楽しさです(もちろんRubyも好きです)
今回の記事では「〜らしい」「〜のようです」「戦争になる?」など、不確かなことだらけの記事になってしまいました。
これを書いた私も、この記事を読んでくださっているみなさんも、この分からないことだらけの記事を自分の言葉で説明できるようになったとき、それが本当の意味でTypeScriptマスターになったということなのかもしれません。
まとめ
ruby = 'ruby'
puts ruby + 'も楽しいけど'
# 結果: rubyも楽しいけど
type TanocConcatenation = (char: string) => string;
const tanocConcatenation: TanocConcatenation = (char: string): string => char + 'も楽しい';
console.log(tanocConcatenation('TypeScript'))
// 結果: TypeScriptも楽しい
記事の全体を通して、認識違い等ありましたらコメントを頂けますと幸いです!
おわりに
スペースマーケットでは一緒に働く仲間を募集しています!
カジュアル面談もやっておりますので、少しでも興味を持ってくださった方は以下のサイトからご応募ください!
スペースを簡単に貸し借りできるサービス「スペースマーケット」のエンジニアによる公式ブログです。 弊社採用技術スタックはこちら -> whatweuse.dev/company/spacemarket
Discussion