🎉

TypeScript入門

2021/10/22に公開

今回はTypeScriptについての記事を書いていこうと思います。

もはやほとんどの現場でTypeScriptは使われていると思うので、しっかりと抑えておきましょう。

そもそもTypeScriptとは


TypeScriptとは、JavaScriptに型定義の機能を加えた言語になります。

TSを使うことで、JSにおける暗黙の型変換によるバグを未然に防げたりと、安全なコードが書けるようになります。

また、GitHubのリポジトリによる言語ごとののランキングではTypeScriptが6位に入っています。

なので、そのくらい人気の言語と言えます。

JavaScriptとTypeScriptのちがいは、ほぼその型システムだけだといえるので、JSに慣れてる人にはかなり馴染みやすいかと思います。

基本的な型定義


まずは、基本的な型定義の仕方について説明していきます。

プリミティブ型

プリミティブ型はJSと同じで以下の7つです。

  • boolean
  • number
  • string
  • bigInt
  • symbol
  • null
  • undefined

それぞれ型を指定する時はこう書けばOKです。


const str: string = "a"
const bool: boolean = true
const num: number = 0
const bigNum: bigint = BigInt(9007199254740991)
const sym :symbol = Symbol('a')
const und: undefined = undefined
const nul: null = null

配列

まずは、配列ですが次の2つの型定義の方法があります。

  • number[]
  • Array<number>

挙動は同じですが、前者の方がわかりやすいので使われることが多いです。


const arr: string[] = ["a", "b", "c"];
const arr: Array<number> = [1, 2, 3];

オブジェクト

次にオブジェクトです。

objectという型もありますが、プリミティブ型以外全てを通してしまうので意味がないです。

なので、キー名と値を指定する必要があります。

また、今回は詳しく説明しませんが、インターフェースを使うと再利用できて便利です。

ちなみに、インデックスシグネチャーを使うことで、柔軟な型を定義することができます。

使い方は[key:T]:Uのように使い、型Tの全てのキーは、型Uの値を持たなければならないよう指定できます。

また、readonly修飾子をつけることで、読み取りのみで編集できない型を指定することができます。


const obj: { foo: "foo"; bar: "bar" } = { foo: "foo", bar: "bar" };

// インデックスシグネチャー
interface IndexSign {
  readonly read: number;
  [seatNUmber: string]: number;
}


const indexObj: IndexSign = {"read": 0,"foo": 1, "bar": 2}
// Cannot assign to 'read' because it is a read-only property.
indexObj.read = 1;

タプル

タプル型とは、個々の要素の型とその順番や要素数に制約を設けられる特殊な配列の型になります。

よく使われてるものでは、関数の引数などがあります。

使い方は以下の通りです。


const charAttrs: [number, string, boolean] = [1, 'patty', true];

enum

セレクトボックスのように、列挙したものの中からひとつだけ限定したい場合などがあると思います。

TypeScriptでは、まずは他の多くの言語と同じようにenum型があります。

また、似たような機能として文字列リテラルというものも使えます。

文字列リテラル型はenum型と比べてもシンプルに記述できて扱いやすく、JavaScriptへのコンパイル後のコードもより短くなるというメリットがあるので、多数派となっています。

それぞれの記述方法は以下の通りです。


// enum型
enum Pet {
  Cat = "Cat",
  Dog = "Dog"
}
// Pet.CatまたはPet.Dogのみを代入できる
let Tom: Pet = Pet.Cat;
// Pet.Dogとイコールではないのでエラーになる
Tom = "Dog";

// リテラル型
// CatまたはDogのみを代入できる
let Tom: "Cat" | "Dog" = 'Cat';
// エラーになる
Tom = "Tiger";

any, unknown, never

最後にany, unknown, neverについて解説していきます。

まずany型ですが、これはいかなる型の値でも受けつける型になります。

ただ、このanyを使うとTypeScriptを使っている意味がなくなってしまうので、使えないように設定している現場も多いかと思います。

次にunknown型ですが、anyの型安全版で任意の型の値を代入できる点は同じですが、型を特定しないとオブジェクトのプロパティやメソッドの参照ができないという特徴があります。

よくわからないと思うので、具体例で説明します。


// anyもunknownもプリミティブ型は代入、参照できる
const any1: any = 1;
const any2: any = "hoge";
console.log(any1);
console.log(any2);
const unknown1: unknown = 1;
const unknown2: unknown = "hoge";
console.log(unknown1);
console.log(unknown2);

// anyはオブジェクトのプロパティを参照できる
const any3: any = { name: "shinya" };
console.log(any3.name);

// unknownは型を指定しないとオブジェクトのプロパティを参照できない
const unknown3: unknown = { name: "shinya" };
// Object is of type 'unknown'.
console.log(unknown3.name);
// 型アサーションで参照できるようになる
type unknown3type = { name: string };
console.log((unknown3 as unknown3type).name);

最後にnever型ですが、これは何も入れることができない型になります。

何に使うんだと思うかもですが、実際に使っている現場はそこまで無いと思うのであまり気にしなくてOKです。

一応説明しておくと、neverを使うことでcase文の漏れを未然にチェックできたり、エラーをthrowする関数に使うことができます。

要は、neverを上手く使うことで開発時にエラーに気づくことができるという感じです。

おわりに


TypeScriptの基本の型について見てきました。

恐らく今はほとんどの現場でTypeScriptが採用されていると思うので、しっかりと身につけておきたいですね。

最後に宣伝です。

0からエンジニアになるためのノウハウをブログで発信しています。
https://hinoshin-blog.com/

また、YouTubeでの動画解説も始めました。
YouTubeのvideoIDが不正ですhttps://www.youtube.com/channel/UCqaBUPxazAcXaGSNbky1y4g

インスタの発信も細々とやっています。
https://www.instagram.com/hinoshin_enginner/

興味がある方は、ぜひリンクをクリックして確認してみてください!

おわり

Discussion