TypeScriptの勉強メモ

# Vue + TypeScript + Nuxtの書き方

## 概要
Vue使いたい！Nuxt使いたい！Vue3系からは、Typescriptを利用しているらしい！
ということで、TypeScript使ったことないので、勉強がてらメモ & リンク集。
（TypeScript部分は動作確認を全てしているわけではないので注意！）

### TypeScriptとは？
マイクロソフトが開発したaltJS（JavaScriptの代替言語、コンパイラーによって、JavaScriptに変換される）

特徴を簡単に言うと、静的な型システムとクラスベースが使えるJavaScript（ただ、クラスベースの開発は、ES2015でもできる）

#### 基本

変数の定義時には、型を宣言する。

デフォルトでは、全ての型に対して、null / undefinedを代入可能。これは、tsconfig.jsonで代入不可能に変更可能。

```typescript
let name: string = "Taro";
name = "Hanako";
name = 1; // エラー発生

const data: number = 100;
data = 101; // constは再定義できないのでエラー

// 配列はこんな感じ
const list: number[] = [1, 2, 3];
// 多次元配列も可能
const multi_list: number[][] = [[1], [2], [3]];

// constは、再定義できないけど、変更はできる。
list[0] = 100;
console.log(list); // 結果：[100, 2, 3];

// 連想配列（ハッシュ）
const obj: { [index: string]: string; } = {
  "a": "ああ",
  "i": "いい"
}

// 列挙型
enum Job {
  Engineer,
  Designer
}

const j: Job = Job.Engineer;
console.log(j); // 結果：0

// タプル型
// ただ、タプル型使うより、クラスの方がおすすめとのこと。
const data: [string, number, boolean];

// 共用型（どっちでもOK）
const data: string | number; 

// 文字列リテラル型（設定した文字列だけを受け取れる）
type Car = "matsuda" | "toyota" | "honda";

```

anyを型として指定すれば、型チェックが行われない。
ただ、原則として、初期値を省略すべきでない。
（TypeScript使う意味がなくなる）

```typescript
let name: any = "Taro";
name = 1; // エラー起きない

let name_any; // 型宣言しないと、型チェックされない。
name_any = "Taro";
name_any = 1; // エラー起きない
```

あと、JavaScript製のライブラリを使いたいと思ったら、型情報が存在しないので、型定義ファイルが必要となる。

#### 関数

関数はこんな感じで書く。

```typescript
function pprint(result: string): string {
  // `${}`はテンプレート文字列と呼ばれる機能
  return `${result}を表示します`;
}

console.log(pprint("hello"));


// 数値型渡すとエラー
console.log(pprint(1));

```

アロー関数
（上の書き方とは、thisを使った場合に、扱い方に違いがあるので、注意！アロー関数でのthisは、宣言された場所をさす。）

```typescript
const printFunc = (result: string): string => return `${result}を表示します`;
```

デフォルト値や、省略可能な変数、可変長引数も宣言できる。

```typescript
function pprint(result1: string = "hello" result2?: string): string {
  return `${result1}, ${result2}を表示します`;
}

function calc(...numbers: number[]) {
  // プログラム
}
console.log(calc(1, 2, 3, 4));
```

#### オブジェクト指向構文
クラス定義

```typescript
Class Pet {
  private name: string;
  private age: number;
  
  // newした時に動く関数
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  
  // 上は、こうやって省略できる。
  constructor(private name: string, private age: number) {}
  
  // getter
  get age(): number {
    return this.age;
  }
  
  // setter
  set age(value: number) {
    this.age = number;
  }

  // method
  public greeting(): string {
    return `こんにちは。${this.age}才の${this.name}ちゃんです。`
  }  
}

const p = new Pet("太郎", 5);
console.log(p.greeting);

```

その他の機能に、
- 継承
- Staticメソッド
- abstract class
- interface
などもちろん使える。

インターフェースは、型注釈として利用可能

```typescript
Interface Pet {
  name: string;
  run(): void;
}

const p: Pet = {
  name: "Taro",
  run() {
    console.log("走る")
  }
}
```

this型もある。

```typescript
class MyClass {
  constructor(private val: number) {}
  
  number(): this {
    return this;
  }
}
```

ジェネリック
>型引数を使用して、実際に利用されるまで型が確定しないクラスや関数を実現するためのものだ。
[TypeScriptの目玉機能「ジェネリック（Generics）」はこうなっている](https://www.buildinsider.net/language/tsgeneric/01)

Pet型を継承した型のみ受け取る関数はこんな感じ？

```typescript
function hi<T extends Pet>(pet: T) {
  pet.say();
}

class Dog extends Pet { ... }
console.log(hi(new Dog));
```

#### 参考
凄くわかりやすかったです。
[速習TypeScript: altJSのデファクトスタンダートを素早く学ぶ！ 速習シリーズ](https://www.amazon.co.jp/%E9%80%9F%E7%BF%92TypeScript-altJS%E3%81%AE%E3%83%87%E3%83%95%E3%82%A1%E3%82%AF%E3%83%88%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%80%E3%83%BC%E3%83%88%E3%82%92%E7%B4%A0%E6%97%A9%E3%81%8F%E5%AD%A6%E3%81%B6%EF%BC%81-%E9%80%9F%E7%BF%92%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E5%B1%B1%E7%94%B0%E7%A5%A5%E5%AF%9B-ebook/dp/B0733113NK)

### Vue + TypeScript

こちら凄く参考になるので、こちら参照。
[TypeScriptでVue.jsを書く – Vue CLIを使った開発のポイントを紹介](https://mae.chab.in/archives/60167)

VuexでTypeScriptを使いたい場合は、デファクトがなさそうです。
[Vue CLI 3.0 で TypeScript な Vue.js プロジェクトをつくってみる](https://qiita.com/nunulk/items/7e20d6741637c3416dcd#43-store)
上記が綺麗かなと思いましたが、どれが正しいのか判断が、難しいです。
厳密さを求めなければ、普通のtsの書き方で良いかも。

Vuexをコンポーネントで呼び出す場合
https://github.com/ktsn/vuex-class

### Nuxt + TypeScript
[typescript-template/template at master · nuxt-community/typescript-template · GitHub](https://github.com/nuxt-community/typescript-template/tree/master/template)

https://github.com/nuxt/nuxt.js/tree/dev/examples/typescript

これを参考にすればOK。Vue + TypeScriptと一緒。
NuxtにもVuexのいい書き方はなさそう。