TypeScript入門

# 著者のバックグラウンド

他の言語経験者でJavascriptは知っている程度です

  • 業務で使う言語: Python
  • API程度なら作ったことある: Go
  • 学生時代: C, Perl
  • 触ったことある: C++, JavaScript

# 書籍

下記の書籍をWingsプロジェクトから寄稿して頂いたのでどの程度まで理解できるか試してみました。

速習TypeScript

https://www.amazon.co.jp/dp/B0733113NK

# TypeScriptの利点

# 環境構築について

簡易的な手法

下記の環境でブラウザ上で動作させることができます。

https://www.typescriptlang.org/play/

## コマンドラインでの環境構築

コマンドラインで実行できると実際の開発の場面で役に立つのでその手法も記述されていました。

node.js の導入

下記で環境ごとに導入が可能です。

https://nodejs.org/en/download/package-manager/

TypeScriptの導入

```
npm install -g typescript
```

 

# TypeScriptの文法

## 変数/データ型

stringの文字型の型を設定している場合に100という数字をいれるとエラーがでます。

 

### 型推論

データ型を指定せずに入力もできます。ただしデータ型は型推論によって数値型が推論されているので下記の場合でもエラーがでます。 

 

### 任意の型

anyを用いれば任意の型が設定できますが特別な場合を覗いて使用しないで下さい。型を設定しているTypeScriptの良さを活かせないからです。

 

### リテラル

特徴的なテンプレート文字列について紹介されていました。

改行コードが不要な点と宣言済みの変数を簡単に埋め込むことができます。

 

### 型アサーション

 

アサーションで型キャストして型を明示的に変更できます。型キャストは型チェクの機能が働きづらくなる原因にもなるので使う場所は最小限に抑える方がベターです。書籍には具体例も載っていました。

 

### ブロックスコープに対応したlet命令

 

`var`宣言の場合はブロック外でも1が表示されます。`let`命令で宣言するとブロック外は無効になります。また同一スコープ内の重複した変数宣言は許可しません。
`let`を使用するとスコープ最小化、重複チェック自動化されるため`let`を変数宣言に使用する方がベターです。

 

### const命令

 

後から再代入することを防いでいます。ただし配列などの各要素の置き換えができます。書籍には具体例も載っていました。

 

### 複数のデータを扱いたい場合

配列・連想配列・列挙型・タプル、多次元配列、配列生成方法、連想配列、列挙型、複数の型が混在したタプル型、共用型

 

複数の型が存在しているため下記のような処理の場合にコンパイルが通るがエラーが出る事象があるため積極的に使用しない方が良い

 

### 型エイリアス

特定の型に対して別名(エイリアス)を設定する仕組みです。

 

下記の理由からインターフェースでできる場合は使用しない方がベターです。

  • エラーメッセージに別名が表示されない
  • 継承・実装では利用できない

### null非許容型

`compileOptions`の`strictNullChecks`オプションにtrueを設定することですべての型でnull/undefinedを禁止出来ます。

 

### 型定義ファイルについて

書籍ではJavaScriptのライブラリを使用する際に必要な型定義ファイルについても言及されていました。
これによってTypeScriptでもJavaScriptのライブラリが使用可能になるようです。

型定義ファイルの詳細

https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html

 

# 関数の種類

function 命令、関数リテラル、アロー関数、オーバーロード、引数・戻り値型としての共用型、型ガード

 

# クラス

下記についての言及もありました。

 

  • クラス命令
  • 静的メンバー
  • 名前空間
  • 階層的な名前空間
  • 継承
  • オーバーライド
  • 抽象メソッド
  • インターフェース: 書籍では抽象クラスと比較してインターフェースの必要性を述べていました。
  • 構造的部分型: インターフェースを継承していなくてもインターフェースのメソッドをすべて備えている場合にオブジェクトの代入が可能
  • 型注釈としてのインターフェース
  • オブジェクト型のリテラル: その場限りの型情報の明示
  • 型としてのthis: thisを用いることでメソッドチェーンのような記述が可能。thisを用いることで継承したクラスがあった場合はその継承したクラスのオブジェクトを返すことが可能
  • ジェネリック: 配列に特定の型情報だけ限定する場合
  • クラスで表現するケース: 型引数は複数与えることも可能
  • クラスの型付
  • ジェネリックメソッド
  • オブジェクトをマージする関数

 

# VS Code

書籍では詳細にVS Codeを用いた実装方法が記述されていました。

# 理解度

 

他の言語で共通の機能もありつつ、経験した言語にはない機能もあって新しい発見がありました。型のないPythonにもType Hintという機能がついたのでここの知識を活かして型のない言語から型付の言語への移行にも取り組んでいこうと思っています。

 

# 最後に

WINGSプロジェクトの書籍レビュアーに応募し、献本して頂いたので、書評を書きました。

文法を理解するのに体系的にまとめられており、実際に使用できるツールの紹介もあったので良かったです。
JavaScriptで作成したものをTypeScriptにリプレースするのに最適だと思います。
本記事では文法の羅列になっていますが書籍では個々の内容の説明も詳しく記述されています。

WINGSプロジェクト
- http://www.wings.msn.to/

TypeScript入門

# 著者のバックグラウンド

他の言語経験者でJavascriptは知っている程度です

- 業務で使う言語: Python
- API程度なら作ったことある: Go
- 学生時代: C, Perl
- 触ったことある: C++, JavaScript

# 書籍

下記の書籍でどの程度まで理解できるか試してみました。

速習TypeScript

https://www.amazon.co.jp/dp/B0733113NK

# TypeScriptの利点

- 開発環境が豊富
- JavaScriptのスーパーセット
- Google, Microsoftで標準採用
- ECMAScript2016に対応

# 環境構築について

## 簡易的な手法

下記の環境でブラウザ上で動作させることができます。

https://www.typescriptlang.org/play/

## コマンドラインでの環境構築

コマンドラインで実行できると実際の開発の場面で役に立つのでその手法も記述されていました。

node.js の導入

下記で環境ごとに導入が可能です。

https://nodejs.org/en/download/package-manager/

TypeScriptの導入

```
npm install -g typescript
```

# TypeScriptの文法

 

### 型推論

データ型を指定せずに入力もできます。ただしデータ型は型推論によって数値型が推論されているので下記の場合でもエラーがでます。 

### 任意の型

anyは特別な場合を覗いて使用しないで下さい。型を設定しているTypeScriptの良さを活かせないからです。

### リテラル

特徴的なテンプレート文字列について紹介されていました。

```js
let mail: string = 'admin@example.com';
let msg = `レビューアー募集中!
書籍の感想下さい。 ${mail}`;
```

改行コードが不要な点と宣言済みの変数を簡単に埋め込むことができます。

### 型アサーション

型キャストして型を明示的に変更できます。型キャストは型チェクの機能が働きづらくなる原因にもなるので使う場所は最小限に抑える方がベターです。書籍には具体例も載っていました。

### ブロックスコープに対応したlet命令

`var`宣言の場合はブロック外でも1が表示されます。`let`命令で宣言するとブロック外は無効になります。また同一スコープ内の重複した変数宣言は許可しません。
`let`を使用するとスコープ最小化、重複チェック自動化されるため`let`を変数宣言に使用する方がベターです。

### const命令

後から再代入することを防いでいます。ただし配列などの各要素の置き換えができます。書籍には具体例も載っていました。

### 配列・連想配列・列挙型・タプル

### 多次元配列

### 配列生成方法

### 連想配列

### 列挙型

### 複数の型が混在したタプル型

複数の型が存在しているため下記のような処理の場合にコンパイルが通るがエラーが出る事象があるため積極的に使用しない方が良い

 ### 共用型

複数の型のいずれかを表す

### 型エイリアス

特定の型に対して別名(エイリアス)を設定する仕組みです。

下記の理由からインターフェースでできる場合は使用しない方がベターです。

- エラーメッセージに別名が表示されない
- 継承・実装では利用できない

### null非許容型

`compileOptions`の`strictNullChecks`オプションにtrueを設定することですべての型でnull/undefinedを禁止出来ます。

### 型定義ファイルについて

書籍ではJavaScriptのライブラリを使用する際に必要な型定義ファイルについても言及されていました。
これによってTypeScriptでもJavaScriptのライブラリが使用可能になるようです。

型定義ファイルの詳細

https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html

# 関数

## function 命令

## 関数リテラル

```js

let triangle = function(base: number, height:number): number {
return base * height / 2;
}
console.log(triangle(10, 5));
```

## アロー関数

```js

let triangle = (base: number, height: number): number => {
return base * height / 2;
};
console.log(triangle(10, 5));
```

## オーバーロード

最初にシグネチャだけ用意して後で関数の詳細を実装する方法。シグネチャ部分で型チェックをする

## 引数・戻り値型としての共用型

```js
function square(value: number): number | boolean {
if (value < 0){
return false;
} else {
return Math.sqrt(value);
}
}
console.log(square(9));
console.log(square(-9));
```

## 型ガード

string型のみ通すようにチェックする。numberの型だと通らないようにする。

# クラス

## クラス命令

```js

class Person {
private name: string;
private sex: string;

constructor(name: string, sex: string) {
this.name = name;
this.sex = sex;
}

public show(): string {
return `${this.name} ${this.sex}`;
}
}
let p = new Person('Rie', 'Female');
console.log(p.show())
```

## 静的メンバー


```js
class Figure {
public static PI: number = 3.14159;
public static circle(radius: number): number {
return radius * radius * this.Pi;
}
}
console.log(Figure.Pi);
console.log(Figure.circle(5));
```

## 名前空間

exportを付けないとアクセス許可されないのでつけます。

## 階層的な名前空間

```js
namespace Wings.MainApp {
export class Hoge {}
export function foo {}
}
let h = new Wings.MainApp.Hoge();
Wings.MainApp.foo();
```

## 継承

```js
class Person {
private name: string;
private sex: string;

constructor(name: string, sex: string) {
this.name = name;
this.sex = sex;
}

public show(): string {
return `${this.name} ${this.sex}`;
}
}

class BusinessPerson extends Person {
work(): string {
reutrn `${this.name}`;
}
}
let p = new BusinessPerson('Rie', 'female');
console.log(p.show());
console.log(p.work());
```

## オーバーライド

superの部分で規程クラスの要素やメソッドを呼び出している。

## 抽象メソッド

```js
abstract class Figure {
constructor(protected width: number, protected height:number) {}
abstract getArea(): number;
}

class Triangle extends Figure {
getArea(): number {
return this.width * this.height / 2;
}
}
let t = new Triangle(10, 5);
console.log(t.getArea());
```

## インターフェース

書籍では抽象クラスと比較してインターフェースの必要性を述べていました。

```js
interface Figure {
getArea(); number;
}

class Triangle implements Figure {
constructor(private width: number, protected height: number) {}
getArea(): number {
return this.width * this.height / 2;
}
}

let t = new Triangle(10, 5);
console.log(t.getArea());
```

## 構造的部分型

インターフェースを継承していなくてもインターフェースのメソッドをすべて備えている場合にオブジェクトの代入が可能

## 型注釈としてのインターフェース

```js
interface Car {
type: string;
run(): void;
}

let c: Car = {
type: 'トラック',
run() {
console.log(`${this.type} is run`);
}
};
c.run();
```

## オブジェクト型のリテラル

その場限りの型情報の明示

```js
let c1: {type: string, width: number} = {type: '軽トラック', weight: 750};
```

## コールシグネチャ

```js
interface Car2 {
(type: string) : string;
}
let c2: Car2 = function(type: string): string {
return `Car type is ${this}`;
}
```

## 型としてのthis

thisを用いることでメソッドチェーンのような記述が可能。
thisを用いることで継承したクラスがあった場合はその継承したクラスのオブジェクトを返すことが可能

## ジェネリック

下記のように配列に特定の型情報だけ限定する場合

```js

let data: Array<number> = [1, 2, 3]
```

クラスで表現するケース

Tの部分が一般化されているため型を設定できる。
型引数は複数与えることも可能

```js
class MyGenerics<T> {
value: T;
getValue(): T {
return this.value;
}
}

let g = new MyGenerics<string>();
g.value = 'Hoge';
console.log(g.getValue());
```

クラスの型付

```js
class Hoge {}
class FooBar extends Hoge {}

class MyGenerics<T extends Hoge> {
value: T;
getValue(): T {
return this.value;
}
}
let g = new MyGenerics<FooBar>();
g.value = new FooBar();
console.log(g.getValue());
```

ジェネリックメソッド

```js
class MyCollection {
static addAll<T>(data: T,... values: T): T[] {
return data.concat(values);
}
}
let x = [10, 15, 30];
console.log(MyCollection.addAll(x, 35, 50));
```

オブジェクトをマージする関数

```js
function merge<T, R>(obj1: T, obj2: R): T & R {
let result = <T & R> {};

for(let key in obj1) {
(<any>result)[key] = obj1[key];
}

for(let key in obj2) {
(<any>result)[key] = obj2[key];
}
return result;
}

class Book {
constructor(private title: string, private price: number) {}
toString() {
return this.title + ' ' + this.price;
}
}
class Logger {
debug() {
console.log(this.toString());
}
}

let m = merge(new Book('JavaScript Beginner', 2980), new Logger());
console.log(m);
```

# VS Code

書籍では詳細にVS Codeを用いた実装方法が記述されていました。

# 最後に

WINGSプロジェクトの書籍レビュアーに応募し、献本して頂いたので、書評を書きました。

文法を理解するのに体系的にまとめられており、実際に使用できるツールの紹介もあったので良かったです。
JavaScriptで作成したものをTypeScriptにリプレースするのに最適だと思います。
本記事では文法の羅列になっていますが書籍では個々の内容の説明も詳しく記述されています。

WINGSプロジェクト
- http://www.wings.msn.to/