27
34

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 3 years have passed since last update.

知識ゼロから始めるTypeScript 〜基本編〜

Last updated at Posted at 2020-03-04

はじめに

現在担当するプロジェクトでTypeScriptが使われていたので学習備忘録です。

  • TypeScriptってよく聞くけどイマイチよく分からない
  • 導入することで何が嬉しいの?

そんな疑問を解決したい。

TypeScriptシリーズ全4回連載中です:writing_hand:
知識ゼロから始めるTypeScript 〜基本編〜 :point_left:今ココ
知識ゼロから始めるTypeScript 〜関数編〜
[知識ゼロから始めるTypeScript 〜クラス編〜]
(https://qiita.com/yukiji/items/3db06601ece7f080b0d0)
[知識ゼロから始めるTypeScript 〜応用編〜]
(https://qiita.com/yukiji/items/e890053e62d2f7edc7c7)

TypeScriptとは

  • Javascriptに静的型付けの定義をすることで堅牢なプログラムを書くことが可能。
  • 型を定義することによりプログラムを動かす前にエラーに気付くことが出来る。
  • 型を定義することによりプログラムを動かす前に意図しない型が代入されるのを防ぐ。

TypeScriptを導入する目的

  • 型安全を確保してバグを減らすのが目的

実行環境

  • MacOS Catalina 10.15.2
  • VScode

使用するモジュールのインストール

$ npm i -D typescript ts-node ts-node-dev

typescript
typescript本体

ts-node
.tsファイルをコンパイルして実行する

ts-node-dev
ts-nodeに依存している
実行したts-nodeをwatchしてくれる。

package.jsonを編集

  • 手軽に実行できるようにscriptsを登録しておく
package.json
"scripts": {
    "dev": "ts-node-dev --respawn"
  }

tsconfig.jsonを作成

$ npx tsc --init

tsconfig.jsonが生成される

細かな設定ができるが、今回はデフォルトの設定でOK

実行サンプル

sample.ts

export {}

let moji: string = "ハロー世界"

console.log(moji)

export{}=モジュール化するという意味。
モジュール化することにより、変数のスコープがグローバルになることを防ぐ。

上記の例は変数mojistring型の型宣言をしている

この場合、文字列(string型)しか受け付けず、string型以外はコンパイルエラーになる。

基本的には変数名: 型の様な書き方をする

実行してみる

$ npm run dev sample.ts

// ハロー世界

tsファイルの内容をJavaScriptにコンパイルして実行してくれる

一度実行するとファイルはウォッチされるので、ファイルを保存するたびに実行されるので便利

型一覧

number型、string型


let year: number = 1969

let name: string = 'foo'

boolean型

let isFinished: boolean = true

array型

let numbers: number[] = [1, 2, 3]

//非推奨の書き方
let strings2: Array<string> = ['Tokyo', 'Nagoya']

//二次元配列の場合
let nijigenHairetsu: number[][] = [
  [50, 100],
  [150, 300]
]

//型が混在する場合
let hairetsu: (string | number | boolean)[] = [1, false, 'Japan']

tuple型

  • 配列の中身の0番目がstring型、2番目がnumber型などにしたい場合に使う
let profile: [string, number] = ['foo', 1969]

any型

  • あまり望ましくない形 (型推論ギブアップ宣言)
  • APIなどでデータが返ってくる場合、そのデータの構造の予測はできないので、エンジニアが指定する必要がある。
import axios from 'axios'

let url: string = 'https://xxx'

axios.get(url).then(function(response) {
  let data: any
  // any型=どんな構造のオブジェクトが返ってくるか分からない
  data = response.data
})

interface型

  • オブジェクトの型を作ることが出来る
interface ObjectInterface {
  name: string
  age: number
}

let object: ObjectInterface = {
  name: 'foo',
  age: 26
}

先ほどのany型のAPIから返されるオブジェクトの構造がわかるときに使用してみる

import axios from 'axios'

export {}

let url: string = 'https://xxx'

axios.get(url).then(function(response) {
  interface Article {
    id: number
    title: string
    description: string
  }
  // APIから返されるデータ構造を指定
  let data: Article[]
  data = response.data
})

void型

  • 関数からの戻り値がないことを期待するような型
  • 関数には必ずしもreturnがあるわけでは無い。
function returnNoting(): void {
  console.log('I dont return anything')
}

console.log(returnNoting())

null型、undefined型

  • そのまんま

let absence: null = null

let data: undefined = undefined

never型

  • 例外を起こす関数や呼び元に戻ってこない関数の戻り値に対応する型
function error(message: string): never {
  throw new Error(message)
}

object型

  • オブジェクトの構造がわかっている場合は、各種プロパティに対しても型宣言する。
let profile2: { name: string, age: number } = { name: 'foo', age: 26 }

型エイリアス(Type Aliases)

  • 一度作成した型を流用できる。

type Mojiretsu = string

const fooString: string = 'Hello'
const fooString2: Mojiretsu = 'Hello'

const example1 = {
  name: 'foo',
  age: 26
}

type Profile = {
  name: string,
  age: number
}

const example2: Profile = {
  name: 'buzz',
  age: 27
}

// example1のデータ構造を設定できる
type Profile2 = typeof example1

unknown型

  • ざっくり言うと型安全なany型
  • any型を積極的に使っているとコンパイルエラーにはならないものの、実行時にエラーになってしまう。
  • 一旦フワッと型定義したいときにany型に依存するのではなく暫定的にunknown型を定義する
  • typeofを使ってある特定の型であることを確認しながら安全にコードを実行させる仕組みのことをタイプガードという
unknown.ts
const kansu = (): number => 26

let numberUnknown: unknown = kansu()

// typeofを使って型を絞る
if (typeof numberUnknown === 'number') {
  let sumUnknown = numberUnknown + 10
}

intersection型

  • 既存の型を再利用して新たな型を作る
type Picher1 = {
  throwingSpeed: number
}

type Batter1 = {
  battingAverage: number
}

const Daimaou: Picher1 = {
  throwingSpeed: 154
}

const Ochiai: Batter1 = {
  battingAverage: 0.367
}

type TwoWayPlayer = Picher1 & Batter1

const Tsuneta: TwoWayPlayer = {
  throwingSpeed: 154,
  battingAverage: 0.367
}

union型

  • 型のor的な感じ
  • 下の例だとnumber型string型のどちらも対応した型宣言ができる
let value: number | string = 1
value = 'foo'
value = 100

Literal型

  • 変数に代入されるパターンを設定したい時
  • 例えばstring型でも「この文字列しか受け付けない」様なパターンを作れる
let dayOfTheWeek: ''|''|''|''|''|''|'' = ''
dayOfTheWeek = ''

let month: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 = 1
month = 12

enum型

  • 数値や文字列を列挙するときに便利
  • 自動的に番号を付与してくれる
  • 数値は設定できる(初期値は0)
enum Months {
  //初期値は0なので1を設定
  January = 1,
  February,
  March,
}

console.log(Months.January)
// 1

enum COLORS {
  RED = '#FF0000',
  BLUE = '#0000FF'
}

let green = COLORS.GREEN
// 追加も可能

補足

ワークスペースのtypescriptを使用する

VScodeにはデフォルトでTypeScriptがインストールされている。

しかし、基本的にはプロジェクト毎に管理したいのでpackage.jsonでインストールしたTypeScriptを使いたい。

①VScode右下のステータスバーTypeScript横の数字(画像では3.8.3)をクリックする
スクリーンショット 2020-03-12 19.25.39.png
ワークスペースのバージョンを使用をクリック
スクリーンショット 2020-03-12 19.25.49.png
これで完了。
大事な設定なのでしっかり行いたい。

ts-nodeでエラーが出たとき

  • パッケージのバージョン履歴を調べて一つずつ試していく。
  • エラーが出ないバージョンをインストールして対処
$ npm info ts-node versions
モジュールの削除
npm uninstall -D ts-node
モジュールのインストール
npm uninstall -D ts-node@x.x.x

まとめ

型宣言は変数に対して制約が強くなるような型を定義することが理想的。
型安全なコードを書いて堅牢なプログラムを書いていきたい:metal:

27
34
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
27
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?