自分用メモ: Typescript(随時更新する)

## Overloads
たまにこういう事やりたい。
Aの引数を入れたらBの戻り値、Cの戻り値を入れたらDの戻り値を返す関数やメソッドの定義

```typescript
function HogeFunc(param: 1 | 2): 1 | 2 {
  if (param === 1) {
    return 1
  }
  return 2
}
const checkType = HogeFunc(1)
// 型: const checkType: 1 | 2
```

しかし、こう定義すると1を入れても1又は2の型で推論される (当たり前
その時に使うのがOverloads

```typescript
function HogeFunc(param: 1): 1
function HogeFunc(param: 2): 2
function HogeFunc(param: 1 | 2): 1 | 2 {
  if (param === 1) {
    return 1
  }
  return 2
}
const checkType = HogeFunc(1)
// 型: const checkType: 1
const checkType = HogeFunc(2)
// 型: const checkType: 2
```

これで、1入れたら1、2入れたら2が来るのを表現できる。

ちなみにこうやって、3入れたらvoid返すなど、実装にそってない表現をしようとすると、以下のようにエラーがでる

```typescript
function HogeFunc(param: 1): 1
function HogeFunc(param: 2): 2

// 追加した奴
// 型エラー: [ts] オーバーロード シグネチャは関数の実装に対応していません。 [2394]
// function HogeFunc(param: 3): void (+2 overloads)
function HogeFunc(param: 3): void

function HogeFunc(param: 1 | 2): 1 | 2 {
  if (param === 1) {
    return 1
  }
  return 2
}
const checkType = HogeFunc(1)
```

インターフェースや抽象クラスのメソッドのオーバーロードの作法

```typescript
abstract class Test {
  public abstract a(params: number): number
  public abstract a(params: string): string
}

class A implements Test {
  public a(params: number): number
  public a(params: string): string
  public a(params: number | string): number | string {
    if (typeof params === 'number') {
      return 1
    }
    return ''
  }
}
```

割と使うので俺頑張って覚えてくれ


## module.d.ts
***.d.tsファイル言語レベルで*.tsとは違う扱いがされる**
参考: https://github.com/k-okina/book-management/pull/11

[このリンク](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-d-ts.html)の内容をとりあえず翻訳

> This is the module template file. You should rename it to index.d.ts and place it in a folder with the same name as the module.
For example, if you were writing a file for "super-greeter", this file should be 'super-greeter/index.d.ts'
> これはモジュールテンプレートファイルです。 ファイル名をindex.d.tsに変更して、モジュールと同じ名前のフォルダに配置する必要があります。
たとえば、 "super-greeter"のファイルを作成する場合、このファイルは 'super-greeter/index.d.ts'にする必要があります。

> If this module has methods, declare them as functions like so.
> もしこのモジュールにメソッドがあるなら、このような関数として宣言します。

```typescript
export as namespace myLib;

export function myMethod(a: string): string;
export function myOtherMethod(a: number): number;
```

> You can declare types that are available via importing the module
> モジュールをインポートすることで利用可能な型を宣言できます

```typescript
/*~ You can declare types that are available via importing the module */
export interface someType {
    name: string;
    length: number;
    extras?: string[];
}
```

> You can declare properties of the module using const, let, or var
> const、let、またはvarを使用してモジュールのプロパティを宣言できます

```typescript
export const myField: number;
```

> If there are types, properties, or methods inside dotted names of the module, declare them inside a 'namespace'.
> モジュールのドット付きの名前の中に型、プロパティ、またはメソッドがある場合、それらを 'namespace'内に宣言します。

```typescript:yourModule
export namespace subProp {
    export function foo(): void;
}
```

> For example, given this definition, someone could write:
> たとえば、この定義があると、誰かが次のように書くことができます。

```typescript
import { subProp } from 'yourModule';
subProp.foo();
// or
import * as yourMod from 'yourModule';
yourMod.subProp.foo();
```