TypeScriptの基本【RaiseTech フロントコース#10】

悩んでいる人

TypeScriptってよく聞くけどなんなんだろう

本記事では、TypeScriptを初めて扱う方向けにTypeScriptの基本的な考え方だったり、使い方について解説していきます。

また、本記事は、Raise Techのフロントエンドエンジニアコースの受講記でもあります。
こちらの記事は、第9回の講義のまとめとなります。

スポンサーリンク

目次

TypeScriptって何?

まずは公式サイトを見てみます。

https://www.typescriptlang.org/

・Javascriptに追加の構文を加えることで、エディターとの連携をサポートしてエラーの発見を早くする。
・TypeScriptのコードはJavaScriptに変換されて、JavaScriptが動作するところであればどこでも正常に動作する。
・型推論を用いて、コードを追加することなく優れたツールを提供する。

といった感じになんだか難しいことが書いてありますねぇ。。

ざっくりいうと、JavaScriptに型の概念を取り入れたものがTypeScriptとなります。

考える人

型ってなによ?

型とは、値の種類のことです。

例えば、人が11を足してと言われれば2と答えそうですが、プログラミングの世界では2なのか11となのか迷ってしまいます。

const test1 = 1 + 1;
console.log(test1); //2
const test2 = "1" + "1";
console.log(test2); //11

なので型をつけて1というものが、数字なのか文字なのかを定義することでより厳密に処理を行うことができるようなるといった感じです。

この型を定義することができるのがTypeScriptということですね。

TypeScriptの型について

TypeScriptにおける基本的な型が以下になります。

● String型 ・・・文字列
● Number型・・・
数値
● Boolean型・・・
真偽値
● Array型・・・
配列
● Tuple型・・・
タプル
● Enum型・・・列挙
● Any型・・・
型チェック無効化
● Void型・・・
型がない
● Null型・・・
全ての方のサブタイプ
● Undefind型・・・全ての方のサブタイプ
● Never型・・・
属する値のない型
● Object型・・・
オブジェクト
● 型アサーション
・・・値の型情報を上書きする

string

let sports: string = "soccer"
sports = 1
// Type 'number' is not assignable to type 'string'
sports = "baseball"

sportsは文字列と定義しているのに、数値(1)を代入しようとしているのでエラーがでる。

正しく文字列を代入すればエラー無くいけます。

number

let age: number = 31;
age = "31歳です";
//Type 'string' is not assignable to type 'number'.
age = 32;

ageは数値として定義しているのに、文字列を代入しようとしているのでエラーがでる。

boolean

// OK
let isFlag: boolean = true;
// NG
let isOpen: boolean = "true";

truefalse を見ています。文字列trueと入れてもダメです。

Array

型名[] か Array<型名>のどちらかで指定する。

const names: string[] = ["山田", "鈴木", "伊藤"];
names.push("高田");
names.push(111);

const names: Array<string> = ["山田", "鈴木", "伊藤"];
names.push("高田");
names.push(111);

配列の中身には、文字列を指定しているので、names.push(111);でエラーがでます。

Tuple型

複数の値を保持することができる。配列によく似ている。

let user: [string, number];
user = ["オカ", 32];
console.log(user);
//["オカ", 32]
console.log(user[1]);
// 32

Enum型

enum Color {
  red,
  green,
  blue
}
let red: number = Color.red;
let green: number = Color.green;
let blue: number = Color.blue;
console.log(red, green, blue);
//
0
1
2

よくわかんない。。。w

Any型

let anything: any = "なんでもOK";
anything = 100;
console.log(anything);
//100
anything = true;
console.log(anything);
//true

型の不明な変数に対して使う。なるべく使わないようにする。

Void型

let message = (): void => {
  console.log("元気ですか!?");
};
message();

戻り値のない関数のときに、返り値の型としてvoidを指定する。

NullとUndefined

const val1: null = null;
val1 = 1;
// Cannot assign to 'val1' because it is a constant.
const val2: undefined = undefined;
val2 = "text";
//Cannot assign to 'val2' because it is a constant.

基本的に、単体での使用はなく他の型と組合わせて使うことが多い。

Never

型を持たない方を表すもの。

とありましたがイマイチわからん。

ので参考になりそうな記事。

https://qiita.com/macololidoll/items/1c948c1f1acb4db6459e

Object

const user: { name: string; age: number } = {
  name: "オカ",
  age: 20
};
console.log(user.tel);
// Property 'tel' does not exist on type '{ name: string; age: number; }'

未定義のプロパティにアクセスすると警告される。

type / interface

複数の箇所で同じ型を使いまわしたい時に使う。

//type
type User = {
  name: string;
  age: number;
};
const user: User = {
  name: "オカ",
  age: 31
};
console.log(user);

//interface
interface User {
  name: string;
  age: number;
}
const user: User = {
  name: "オカ",
  age: 31
};
console.log(user);

複合的な型

type SampleA = {
  str: string;
  num: number;
};
type SampleB = {
  str: string;
  flg: boolean;
};
type SampleC = SampleA & SampleB;
const data: SampleC = {
  str: "おーい",
  num: 1,
  flg: true
};
console.log(data);
//{str: "おーい", num: 1, flg: true}

型と型を&でつなぐことで新しい形を生成できる。

Union

let val1: string | number;
val1 = "おーい";
val1 = 1;
val1 = true; //エラー

type Result = "success" | "error";
const result: Result = "";

パイプラインを使用するパターン。

型アサーション

// 型アサーション
interface Test {
  foo: number;
}

const test: Test = {} as Test;
test.foo = 123;

テスト型の変数testを宣言。

Optional

// error
type User = {
  name: string;
  age: number;
  weight?: number;
};
const user: User = {
  name: "おか",
  age: 31
};

// ok
type User = {
  name: string;
  age: number;
  weight?: number;
};
const user: User = {
  name: "おか",
  age: 31
};

プロパティが足りていないのでエラーがでるが、weight: number;weight?: number;に書き換えることで任意と指定することができる。

オカ

いったんここまでで、型の紹介を終えます。
いやー僕もわからないものが結構あったので、コード書いて理解ふかめていきます。

Generics(ジェネリクス)について

型引数を指定することで、クラスやコンポーネント・関数などを使用する時に、実際に型を決定できる仕組みです。

1つ例を見ていきます。

type Sample<T> = {
  value: T;
};
const val1: Sample<string> = {
  value: "ハロー"
};
console.log(val1);
// {value: "ハロー"}
const val2: Sample<string> = {
  value: true
};
// Type 'boolean' is not assignable to type 'string'

関数名(型)名<型名>となりますジェネリクスを使用する場合には、<T>のようにTを使うことが多いみたいです。

関数のときのパターンも見てみます。

// functionを使った宣言
const testFunc = function <T>(arg: T): T {
  return console.log(arg);
};

testFunc<string>("ハロー");
testFunc<string>(1);

// アロー関数
const testArrow = <T extends {}>(arg: T): T => {
  return console.log(arg);
};
testArrow<string>("こんにちは");
testArrow<string>(true);
CodeSandbox
raisetech10_Generics(ジェネリクス)について - CodeSandbox raisetech10_Generics(ジェネリクス)について by takahiro-okada using parcel-bundler

Utility Typesについて

Utility Typesとは型変換を行うための便利な機能になります。

一度定義した方を元に、場面に合わせて型を変換できます。

Partial<T>

type User = {
  name: string;
  age: number;
  gender: string;
};
type User1 = Partial<User>;
// type User1 = {
//   name?: string | undefined;
//   age?: number | undefined;
//   gender?: string | undefined;
// }

全てOptinalに変換してくれる。

Required<T>

type Todo = {
  task?:string;
  status?:boolean
}
type Todo1 = Required<Todo>
// type Todo1 = {
//   task: string;
//   status: boolean;
// }

optionalのプロパティを全て必須のプロパティに変換する。

Readonly

type Todo = {
  task?: string;
  status?: boolean;
};
type Todo2 = Readonly<Todo>;
const todo: Todo2 = {
  task: "掃除",
  status: true
};
console.log(todo.task); //掃除
todo.task = "変更不可";
// Cannot assign to 'task' because it is a read-only property.

読み取り専用で、taskは変更不可とでます。

Record<T,U>

type Todo = {
  task: string;
  status: boolean;
};
type Todo3 = Record<number, Todo>;
const todo3: Todo3 = {
  "No.1": {
    task: "掃除",
    status: true
  },
  1: {
    task: "掃除",
    status: true
  }
};

プロパティがT型、値がU型の型を作成する。

Pick<T, U>

type Todo = {
  task: string;
  taskMin: number;
  status: boolean;
};
type Todo4 = Pick<Todo, "task" | "taskMin">;
const todo4: Todo4 = {
  task: "掃除",
  taskMin: 30,
  status: true
  //errorになる
};

T型に含まれているU型のプロパティを取り出して新しい形を作成する。

Omit<T, U>

type Todo = {
  task: string;
  taskMin: number;
  status: boolean;
};
type Todo5 = Omit<Todo, "task">;
const todo5: Todo5 = {
  task: "掃除",
  taskMin: 30,
  status: false
};

T型に含まれるU型のプロパティを除去した新しい形を作成する。

ReturnType<T>

type Todo = {
  task: string;
  taskMin: number;
  status: boolean;
};
const getTask = (): Todo => {
  return todo;
};
type TypeA = ReturnType<typeof getTask>;
// type TypeA = {
//   task: string;
//   taskMin: number;
//   status: boolean;
// }

関数型のTの戻り値の型を取り出す

設定ファイルについて(tsconfig.json)

▼公式ドキュメント

https://www.typescriptlang.org/docs/handbook/tsconfig-json.html

TypeScript導入時に、デフォルトの設定が適用されます。
配置する位置はプロジェクトのルートディレクトリ直下に配置。

まとめ

やっとTypeScriptに入りました。

バックエンドはほぼやったことないので、あまり型と言われてもピンときていませんでしたが、実際に手を動かしながらやることで少しずつ型の重要性がわかってきた気がします。

実際にプロダクトを作っていくともっとありがたさを感じるのだろうと思います。

スポンサーリンク

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
目次
閉じる