PHP脳のままTypeScriptを書いたら怒られた話|初心者がつまずいた型の壁

PHP脳のままTypeScriptを書いたら怒られた話|初心者がつまずいた型の壁

こんにちは、キノです。

今の会社ではJavaScriptとPHP・WordPress中心の運用寄りの仕事をしていますが、React系のフロントエンドエンジニアを目指しています。その一環で避けて通れなかったのがTypeScriptです。

正直なところ、最初の数週間はかなり苦戦しました。この記事では、実務ではJavaScriptとPHPしか書いてこなかった人がTypeScriptで最初にぶつかる壁を、実際につまずいたポイントごとに振り返ります。同じ立場でTypeScriptを勉強し始めた人の参考になればと思います。

そもそもJavaScriptとTypeScriptは何が違うのか

TypeScriptの前に、まずJavaScriptとの関係を整理しておきます。WordPressのテーマ開発で素のJavaScriptは触ってきましたが、実はJavaScriptもPHPと同じく型を意識しなくても動いてしまう言語です。

// JavaScript
let name = "kino";
name = 123; // エラーにならず普通に動いてしまう

TypeScriptは、このJavaScriptに型のルールを追加したものと考えるとしっくりきます。書いたTypeScriptのコードは、最終的にはコンパイルされて普通のJavaScriptに変換されてから動きます。つまり実行時の挙動そのものはJavaScriptと同じで、「書いている途中でミスに気づけるかどうか」が一番の違いです。

// TypeScript
let name: string = "kino";
name = 123; // Type 'number' is not assignable to type 'string'.

JavaScriptやPHPしか書いてこなかった自分にとっては、「JavaScriptもPHPと同じく緩い」「TypeScriptはそこに型のチェックを足したもの」という順番で理解すると、TypeScript固有の考え方だけに集中できて楽でした。

スポンサーリンク

PHPとTypeScriptで一番違うのは「型を先に決める」感覚

PHPは変数の型を意識しなくてもとりあえず動きます。

$name = "kino";
$name = 123; // これも通ってしまう

一方TypeScriptでは、変数の型を最初に決めて、それ以外の値を入れようとするとコンパイル時点で怒られます。

let name: string = "kino";
name = 123; // Type 'number' is not assignable to type 'string'.

「動いてから直す」PHPの感覚のまま書いていた僕は、最初この赤い波線が出るたびに戸惑っていました。でも慣れてくると、実行前にミスに気づけるというのがTypeScriptの一番のメリットだと実感できるようになりました。

スポンサーリンク

「Property does not exist on type」で詰んだ話

最初に一番よく出たエラーがこれでした。

type User = { name: string };
const user: User = { name: "kino" };
console.log(user.age); // Property 'age' does not exist on type 'User'.

WordPressのテーマ開発では、連想配列に後から適当にキーを足していくことが多かったので、「決めた型にないプロパティは使えない」という制約に最初は戸惑いました。裏を返せば、「このオブジェクトに何が入っているか」を型を見るだけで把握できるということで、これはチーム開発で他人のコードを読むときにありがたい仕組みだと後から気づきました。

「anyを使うな」と言われても、最初は理由がわからなかった

学習を進める中で「anyは極力使わない」というアドバイスをよく見かけました。最初は「型が分からない時に使えばいいのでは?」と思っていましたが、実際には次のような問題があります。

function getName(user: any) {
  return user.nam; // typoしてもエラーにならない(本来は user.name)
}

anyを使うと、TypeScriptの型チェックがその部分だけ効かなくなり、PHPのときと同じ「実行するまで気づけないバグ」が復活してしまいます。せっかくTypeScriptを使うなら、anyに逃げずに型を明示する方が、結局は自分を助けることになると理解しました。

interfaceとtypeの違いで地味に詰んだ話

もうひとつ最初につまずいたのが、interfacetypeのどちらを使えばいいのか分からなかったことです。

// interfaceの場合
interface User {
  name: string;
}

// typeの場合
type User = {
  name: string;
};

見た目はほぼ同じですが、大まかには次のように使い分けられることが多いです。

  • interface:オブジェクトの形(プロパティの構造)を定義するときに使われることが多い。あとから同じ名前で機能を追加(宣言のマージ)できる
  • type:オブジェクトだけでなく、ユニオン型("a" | "b"のような複数の型のどれか)なども表現できる

「どちらでも動くのに使い分けがある」という点が、JavaScriptやPHPにはない感覚で最初は混乱しましたが、React関連のコードではpropsの型定義にinterfaceがよく使われている印象があります。

JavaScript・PHP・WordPress出身者がTypeScriptを学ぶときのコツ

数週間つまずいてみて、自分なりに感じたコツをまとめます。

  1. 最初から完璧な型を書こうとせず、まずはコンパイルエラーを1個ずつ消していく感覚で慣れる
  2. anyでごまかしそうになったら、一度手を止めて「本当は何の型が入るべきか」を考える
  3. PHPの連想配列に慣れている人ほど、型定義を先に書く練習をあえて増やす

PHP・WordPressの経験は無駄になるわけではなく、「動的型付けと静的型付けの違い」を体感として理解できているぶん、TypeScriptの型の意味を実感しやすいという利点もあると感じています。これからも学習の記録を残していく予定です。


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です