LoginSignup
4
1

More than 1 year has passed since last update.

TypeScript①(基礎)

Last updated at Posted at 2021-06-23

はじめに

この記事は私がTypeScriptについて学んだ内容を
TypeScript①(基礎)
TypeScript②(型の機能)
TypeScript③(ユーティリティタイプ)
の3回に分けて網羅的に紹介していきます。

①(基礎)では導入方法と様々な型について簡単な紹介
②(型の機能)では型が実際にどういう働きをするのかについて
③(ユーティリティタイプ)では型変換を容易にするユーティリティ型について

参考リンク

Typescriptの導入

TypeScriptのインストール

npm install -g typescript

TypeScriptを使用するプロジェクトフォルダを作成し移動したら
以下のコマンドでtsconfig.jsonを作成

tsc --init

以上でTypeScriptの導入できます。

tsconfig.jsonによる型チェックの厳密さの調整

初期状態のstrict: trueの指定では以下のルールが一括で有効になっています。

  • alwaysStrict
  • noImplicitAny
  • noImplicitThi
  • strictBindCallApply
  • strictFunctionTypes
  • strictNullChecks
  • strictPropertyInitialization

tscong.jsonに追加ルールを指定して型チェックを弱くする

暗黙的なany型を許可
"noImplicitAny": false

null型に他のプリミティブ型の割り当てを許可
"strictNullChecks": false

状況によって上記のようにfalse指定することによって型チェックを弱める事ができます。
ただし、これはJavaScriptプロジェクトを段階的にTypeScriptに移行するために許容されるべきであり、TypeScriptを利用する目的から外れてしまわないように注意が必要です。

基本の型

プリミティブ型

string, number, boolean, symbol, bigint, null, undefinedがあります。

リテラル型

プリミティブ型を細分化したのがリテラル型で、エディターにベタ書きした文字列や数字や真偽値をリテラルを言います。

boolean型

falseまたはtureの値を持つ事ができます。

let flag = true;

number型

16進数、10進数、8進数、2進数をサポートしています。

let decimal: number = 42;
let hex: number = oxee;
let octal: number = 0o213
let binary: number = 0b1001;

string型

文字列を扱います。またダブルクウォート(")、シングルクウォート(')、バッククウォート(`)で囲います。

let name: string = "Jacob";
name = 'Michael';
let myName: string = `my name is ${name}`;

array型

配列型の記述方法は以下の2つがあります。

  • 配列に入る値の型の後ろにブラケット[]をつける。
let data: number[] = [1, 2, 3];
  • Array型で記述する。
let data: Array<number> = [1, 2, 3];

tuple型

配列内の型を指定できます。

let x: [string, number];
x = ["hello", 3]; // OK
x = [3, "hello"]; // Error
x = ["hello", 3, 0]; // Error

any型

any型はどのような値も代入する事ができ、型が不定の時に使われます。
またany型は型チェックを無効にし、コンパイルを通過させることができるので、不定の型でもコンパイルを通してしまう危険な型とも言えます。

unknown型

unknown型はany型と似ていて、どのような値も代入する事ができ、型が不定の時に使われます。
any型と異なる点は、コンパイルを通さないという事です。そのため型安全なanyと呼ばれることもあります。

void型

void型はany型とは逆にundefinednull以外代入することができません。
戻り値を持たない関数の型として利用されます。

null型/undefined型

全ての型はnullまたはundefiendを代入する事ができ、null型、undefiend型というサブタイプの型を得ることができます。
また、nullは意図的にnullを定義した場合にだけ使う事ができ、undefinedは意図的に限らず 変数に何も代入されていない状態を表す。

never型

never型は発生し得ない型を表します。

function log(text: string): never {
  throw new Error(text);
}
function roop(): never {
  while (true) {}
}

object型

object型はプリミティブ以外の値の型で、引数にオブジェクトのみ受け取る関数に使用します。

const obj = { foo: 'foo' };
const obj2: {} = obj;

高度な型

Intersection Types

IntersectionTypesは複数の型をアンバサンド&で結合した型です。

type Address = {
  City: "Seattle";
  state: "WA";
};
type Name = {
  first: "Matthew";
  last: "Smith";
};
type Profile = Address & Name;

Union Types

複数の型のうち一つが当てはまることをします場合に使用します。

let data: number | string | boolean;

クラス

TypeScriptではクラスのインスタンス化をする際、受け取った引数をコンストラクターからメンバー変数に代入します。

class Point {
  x: number;
  y: number;

  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}
const coordinates = new Point(3, 0);

継承

継承(extends)すると継承元のすべてのプロパティとメソッドを受け継ぎ、受け継いだ先で、呼び出しと、追加のメンバーの定義をする事ができます。

class Animal {
  run() {
    console.log("走る!");
  }
}
class Dog extends Animal {
  woof(times: number) {
    for (let i = 0; i < times; i++) {
      console.log("ワン!");
    }
  }
}
const d = new Dog();
d.run();
d.woof(3);
// 結果
// 走る!
// ワン!
// ワン!
// ワン!

superを使って継承元のプロパティを上書きする事ができます。

class Base {
  greet() {
    console.log("こんにちは、いい天気ですね。");
  }
}

class Derived extends Base {
  greet(name?: string) {
    if (name === undefined) {
      super.greet();
    } else {
      console.log(`こんにちは! ${name.toUpperCase()}`);
    }
  }
}

const d = new Derived();
d.greet();           // こんにちは、いい天気ですね。
d.greet("ウィルさん!"); // こんにちは! ウィルさん!

クラスメンバー修飾子(public・private・protected)

  • publicはどこででも参照・実行が可能
  • privateは同一のクラスでのみ参照・実行が可能
  • protectedは継承先でのみ参照・実行が可能

同一クラス内での検証

class Base {
  public name1: string;
  protected name2: string;
  private name3: string;
  constructor() {
    this.name1 = "Ichiro";
    this.name2 = "Jiro";
    this.name3 = "Saburo";
  }
  greet1() {
    console.log(`こんにちは! ${this.name1}`); // OK
  }
  greet2() {
    console.log(`こんにちは! ${this.name2}`); // OK
  }
  greet3() {
    console.log(`こんにちは! ${this.name3}`); // OK
  }
}
const human = new Base();
console.log(human.name1); // Ichiro
console.log(human.name2); // error
console.log(human.name3); // error
human.greet1(); // こんにちは! Ichiro
human.greet2(); // こんにちは! Jiro
human.greet3(); // こんにちは! Saburo

継承先での検証

class Base {
  public name1: string;
  protected name2: string;
  private name3: string;
  constructor() {
    this.name1 = "Ichiro";
    this.name2 = "Jiro";
    this.name3 = "Saburo";
  }
}
class Derived extends Base {
  greet01() {
    console.log(`こんにちは! ${this.name1}`); // OK (public)
  }
  greet02() {
    console.log(`こんにちは! ${this.name2}`); // OK (protected)
  }
  greet03() {
    console.log(`こんにちは! ${this.name3}`); // error (private)
  }
}
const human = new Derived();
human.greet01(); // こんにちは! Ichiro
human.greet02(); // こんにちは! Jiro
human.greet03(); // error

列挙型(Enum

列挙型は、関連する値の集合を編成する方法です。
また数値列挙は自動で0から順に割り振られ、代入した時点から再度割り振られます。

enum Color {
  red,
  white,
  green,
  blue,
  black = 2,
  pink,
  yellow,
}
console.log(Color);
// 結果
// {
//   '0': 'red',
//   '1': 'white',
//   '2': 'black',
//   '3': 'pink',
//   '4': 'yellow',
//   red: 0,
//   white: 1,
//   green: 2,
//   blue: 3,
//   black: 2,
//   pink: 3,
//   yellow: 4
// }

文字列列挙は、数字の自動割り当てはありませんが、別ブロックからもプロパティーを追加することが可能です。

enum Env {
  USER_API = "abcd",
  USER_KEY = "ABCD",
  APP_ID = "0123",
}
console.log(Env);
// {
//   USER_API: 'abcd',
//   USER_KEY: 'ABCD',
//   APP_ID: '0123'
// }

enum Env {
  PUBLIC_KEY = "abcd0123",
}
console.log(Env);
// {
//   USER_API: 'abcd',
//   USER_KEY: 'ABCD',
//   APP_ID: '0123',
//   PUBLIC_KEY: 'abcd0123'
// }

TypeScript②(型の機能)へ

関連記事

TypeScript③(ユーティリティタイプ)

4
1
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
4
1