11
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

エンジニアではない自分がTypeScriptを勉強してみた

Last updated at Posted at 2021-12-15

はじめに

Qiita Advent Calendar 2021の16日目の担当は、6日目に引き続きQiita株式会社プロダクトマーケティングGの中泉(@zumi0)が担当します!

6日目には、非エンジニアがSQLをかけるようになるまでにやったことをまとめたので、興味がある方は読んでいただけると嬉しいです。

さて今回は、エンジニアではない自分がTypeScriptを勉強するために書籍『実践TypeScript』を読んで学んだことをまとめます!

そもそも「なんでTypeScriptを学ぶの?」というところですが、Qiita株式会社のプロダクトであるQiitaQiita TeamQiita JobsのフロントエンドはTypeScriptでかかれているので、今回のAdvent Calendarを機に勉強してみました。

書籍『実践TypeScript』を読んでみた

今回読んだ書籍『実践TypeScript』は、2部構成です。第1部では導入編ということで、開発環境の設定からTypeScriptの基礎、TypeScriptの型の内容が書かれています。第2部は実践編ということで、ReactやVue.js、ExpressなどのフレームワークとTypeScriptをどう使うかについての内容が書かれています。

今回は主にTypeScriptの基本的な内容である、第1部の内容をまとめていきます。

TypeScriptを始める

TypeScriptのインストールは、npmを使う場合は以下のコマンドでできます。

$ npm install -g typescript

インストールしたらtscコマンドを使って、tsconfig.jsonの雛形を作成します。tsconfig.jsonは、TypeScriptコンパイラーの設定ファイルです。このファイルの設定を元に、TypeScriptのファイルはJavaScriptのファイルにビルドされます。
tsconfig.jsonの雛形は、以下のコマンドで作成します。

$ tsc --init

TypeScriptのファイルはJavaScriptのファイルにビルドするには、以下のコマンドで行います。

$ tsc

tsconfig.jsonがあるディレクトリが、プロジェクトルートになります。ビルドする際は、このディレクトリ以下の対象ファイルがビルドされます。何をビルドして、ビルドしないかもtsconfig.jsonを記入することで、設定が可能です。

型注釈(アノテーション)

JavaScriptの課題の一つに、関数の引数や戻り値の型が決まっていないためにエラーが出てしまうということがありました。TypeScriptは、そのJavaScriptの課題を解決することができます。すなわち、TypeScriptでは変数や定数などに型を付与することができます。このことを型注釈(アノテーション)と言います。

型注釈の仕方は、以下のような感じでできます。

function add(x: number, y: number): number {
    return x+y
}

引数の型注釈の方法は、今回であればxyの後に: numberと記載することで指定しています。関数の戻り値の型注釈は、function add(x: number, y: number)の後に: numberと記載することで指定しています。

さきほどは1つの型を付与していましたが、複数の型を付与することもできます。
例えば、number型の値を代入することがほとんどだがnullかもしれない値を代入するかもしれない状況がある場合は、以下のような記述をすることで解決することができます。型と型を|でつないであげればいいだけです。

function twoTimes(x: number | null) {
    return 2 * x
}

クラスと継承

TypeScriptでは、クラスの構築と継承を行うことができます。クラスは名前とコンストラクタ関数を宣言する必要があります。new演算子を使うことで、インスタンス化できます。今回は書籍に掲載されているクラスを引用させていただきます。

class Creature {
  numberOfHands: number
  numberOfFeet: number
  constructor(numberOfHands: number, numberOfFeet: number) {
    this.numberOfHands = numberOfHands
    this.numberOfFeet = numberOfFeet
  }
}

const creature = new Creature(0,4)

上記のCreatureクラスを継承したクラスは、以下のように書くことができます。constructor関数内にあるsuper関数は、親クラスのコンストラクタ実行に相当します。こちらも書籍の方から引用させていただきました。

class Dog extends Creature {
  bark: string
  constructor(bark: string) {
    super(0,4)
    this.bark = bark
  }
  barking() {
    return `${this.bark}! ${this.bark}!`
  }
  shakeTail() {
    console.log(this.barking())
  }
}

const dog = new Dog('bow-bow')

型推論

TypeScriptの基本で型注釈の話をしました。型注釈は必ずする必要があるわけではありません。また、TypeScriptには変数などの宣言時に代入された値から、その値の型を推論することができます。

例えばxという変数に0を代入した場合に推論される型はnumber型になります。

// 代入した値
let x = 0
// 推論される型
let x: number

上記はletを使って変数を宣言していますが、constを使う場合は型推論が変わります。constで宣言された値は固定値になるため、以下のようになります。

// 代入した値
const y = 0
// 推論される型
const y: 0

型推論とは話は変わりますが、letを使ってconstのように型を付与することも可能です。

// 代入した値
let z: 0 = 0
// 型
let z: 0

アップキャストとダウンキャスト

TypeScriptでは抽象的な型をより詳細な型に付与したり、逆に詳細な型を抽象的な型に付与することができます。抽象的な型から詳細な型を付与することをダウンキャスト、逆をアップキャストと言います。ダウンキャストは、より厳密な型を付与したいときにを行います。アップキャストは、提供されている関数の戻り値が指定されていてうまく使えないなどといったときに行うことがあります。

型の互換性

TypeScriptでは、型をチェックする際に型の互換性を使っています。どういうことか簡単に説明すると、変数xを変数yに代入できた場合は互換性があり、代入できない場合は互換性がないと言えます。どういう場合に代入可能かというと、抽象的な型に詳細な型を代入するときは代入可能です。

書籍に記載されている例を引用し確認していきます。

let n1: 0 = 0
let n2: number = n1  // No Error
let n3: number = 0
let n4: 0 = n3       // Error!

ここで変数n3number型の値であり、変数n4number型よりもより厳密な型になっているため代入不可、すなわち互換性がないと言えます。
逆に変数n1を変数n2に代入する場合は、より厳密な型からそうではない型への代入になるため代入可能で、互換性があると言えます。

Generics

Genericsを用いると、型の決定するタイミングを遅らせることが可能です。

本来であれば、以下のように最初に型を付与する必要があります。

interface Color {
  value: string
}

しかし、Gerericsを用いることで型を付与するタイミングをずらすことができます。

// このタイミングでは型を付与していない
interface Color<T> {
  value: T
}

// このタイミングで型を付与している
const color1: Color<string> = { value: 'red'}

Conditional Types

Conditional Typesは、書籍から引用すると「型の互換性を条件分岐にかけ、型推論を導出する型」だそうです。

どういうことか書籍の例を見ていきます。
以下の例では、Tの型がstring型である場合はtrueとなり、Tの型がstring型でない場合はfalseとなります。 

type IsString<T> = T extends string ? true : false
type X = IsString<'test'> // type X = ture
type Y = IsString<0>      // type Y = false

さいごに

今回は非エンジニアの自分が書籍『実践TypeScript』の主に第1部の内容をまとめてみました。大分ボリュームのある内容だったので、一部をピックアップしながらといった内容になりました。まだまだ道なかばといったところですが、TypeScriptがなんとなくわかってきた感じがします。本来であれば実際に使ってみて、その恩恵を受けられると一番いいなと思いました。


Qiita Advent Calendar 2021の17日目は、Qiita株式会社 CX向上G の@ohakutsuが担当します!

11
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?