FlowのドキュメントにあるコードをひたすらTypeScriptのPlaygroundで試す

Flow 0.74
Typescript 2.9

TypeScriptの設定は以下な感じ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5840/3adb07c7-12e0-dafe-0ed6-d1bff31a6a7c.png)

# 先にまとめ

やってみることによって学びがあった。良かった。

* FlowのObjectTypeは必要なプロパティがあれば同じ型として使えるがTypeScriptの場合はそうではない。
* 基本型はだいたい同じだが、mixedがないのとvoidの挙動が違う。
* Maybe型がない。
* TypeScriptは型を書かないとanyになるがFlowは推論は推論してくれる

多分、お互いに似たようなことはできるが、実際にやるにはそれなりの経験が必要そうだ。逆をやってみるのも面白そう。
これをやってみた感じからするとFlowのほうが好み。

# Stringへの暗黙型変換

https://flow.org/en/docs/types/primitives/#toc-strings

```javascript
// @flow
"foo" + "foo"; // Works!
"foo" + 42;    // Works!
"foo" + {};    // Error!
"foo" + [];    // Error!
```

TypeScriptはエラーにならなかった。+演算子を使うときは気をつけて。


- [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0D%0A%22foo%22%20%2B%20%22foo%22%3B%20%2F%2F%20Works!%0D%0A%22foo%22%20%2B%2042%3B%20%20%20%20%2F%2F%20Works!%0D%0A%22foo%22%20%2B%20%7B%7D%3B%20%20%20%20%2F%2F%20Error!%0D%0A%22foo%22%20%2B%20%5B%5D%3B%20%20%20%20%2F%2F%20Error!)
- [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQAiStbNAalK9yBuUEUAdVgCcBrAZwEIU0NtQAWAJiNG5POvsb4WAbwC+XHmACiFCpQZ5mOANoBdCcWmz5QA)

# Maybe

https://flow.org/en/docs/types/primitives/#toc-maybe-types

```javascript
// @flow
function acceptsMaybeString(value: ?string) {
  // ...
}

acceptsMaybeString("bar");     // Works!
acceptsMaybeString(undefined); // Works!
acceptsMaybeString(null);      // Works!
acceptsMaybeString();          // Works!
```

残念ながら未対応。自前で実装するしかなさそう。


* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0D%0Afunction%20acceptsMaybeString(value%3A%20%3Fstring)%20%7B%0D%0A%20%20%2F%2F%20...%0D%0A%7D%0D%0A%0D%0AacceptsMaybeString(%22bar%22)%3B%20%20%20%20%20%2F%2F%20Works!%0D%0AacceptsMaybeString(undefined)%3B%20%2F%2F%20Works!%0D%0AacceptsMaybeString(null)%3B%20%20%20%20%20%20%2F%2F%20Works!%0D%0AacceptsMaybeString()%3B%20%20%20%20%20%20%20%20%20%20%2F%2F%20Works!)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQkCuA7AxgFwJazaAIYYYCmADlgM4CyhAngEakDKWATjmgOYAUAboWgpSALlAB+Khy7cAlKADeiUKBCgAdFsQBfRImJlKtBszacevAESNC7K3IDcql+oDqsdgGsqAQgMkFNR0TKwylugAJqSQXKSRTmpgHt5+AUbBpmEWfGgo0NCJLqrunj7+hkEmoeayvEXFxaWpvkA)

# Mixed

https://flow.org/en/docs/types/mixed/

```javascript
// @flow
function stringify(value: mixed) {
  // ...
}

stringify("foo");
stringify(3.14);
stringify(null);
stringify({});
```

そもそもmixedが存在しない模様。
Union型で代用できそうな気はする。

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Afunction%20stringify(value%3A%20mixed)%20%7B%0A%20%20%2F%2F%20...%0A%7D%0A%0Astringify(%22foo%22)%3B%0Astringify(3.14)%3B%0Astringify(null)%3B%0Astringify(%7B%7D)%3B)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQBjWA7AzgF1KgrmlgE4CWAphqALygDeiooAqgMoBcoARE2iVmQBNQLLAEN+GTgBoGoAJIAVDpzljoAT2myAYgCVl2oqLTIynRAF8A3IkRZ1ABzKgAwrALF11UABIA0mTqGAA89k6wkLjuhKQUAHw2KOjYoHyiGhxuHkReNADkink2qJg4aLBOmdGe3nnlTkWgIKB1FWR5qZTlOKKu1TlAA)


# Variables
## Reassigning variables

https://flow.org/en/docs/types/variables/#toc-reassigning-variables

```javascript

let foo = 42;

if (Math.random()) foo = true;
if (Math.random()) foo = "hello";

let isOneOf: number | boolean | string = foo; // Works!
```

TypeScriptでは代入した時点で foo が numberと決まってしまう。true や "hello"は代入しようとすると型エラーに。flowは型の再設定が可能で、Union Typeになる。

以下の様に書いてあげるとエラーは消える

```javascript
let foo: number | boolean | string = 42;

if (Math.random()) foo = true;
if (Math.random()) foo = "hello";

let isOneOf: number | boolean | string = foo; // Works!
```

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=let%20foo%20%3D%2042%3B%0A%0Aif%20(Math.random())%20foo%20%3D%20true%3B%0Aif%20(Math.random())%20foo%20%3D%20%22hello%22%3B%0A%0Alet%20isOneOf%3A%20number%20%7C%20boolean%20%7C%20string%20%3D%20foo%3B%20%2F%2F%20Works!)
* [Flowで確認](https://flow.org/try/#0DYUwLgBAZg9jEF4IBYBMBuAUJgllCAFALICGYAFgHQBOJAdgCYwC2BAlG9HIhGNQK4gseQqQo16TVhy7wkAInIhgwGPKyZQkHAGcA8nRB6oALgh1+zAEYhqEAD4QrcUPQcQdfHHQDmPWDDoEAD0wRAA6jDUANY6AIRAA)


# Function this

https://flow.org/en/docs/types/functions/#toc-function-this

```javascript
function method() {
  return this;
}

var num: number = method.call(42);
// $ExpectError
var str: string = method.call(42);
```

TypeScriptでは暗黙のanyでエラーになる。
TypeScriptなら以下でどうだろうか。

```typescript

function method<T>(this: T): T {
  return this;
}

var num: number = <number>method.call(42);
// $ExpectError
var str: string = <number>method.call(42);
```

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=function%20method()%20%7B%0D%0A%20%20return%20this%3B%0D%0A%7D%0D%0A%0D%0Avar%20num%3A%20number%20%3D%20method.call(42)%3B%0D%0A%2F%2F%20%24ExpectError%0D%0Avar%20str%3A%20string%20%3D%20method.call(42)%3B%0D%0A)
* [Flowで確認](https://flow.org/try/#0GYVwdgxgLglg9mABAWwKZQBZwCYAoCUiA3gFCKIBO6IFSmMAzgNwkC+JJAbgIYWJghkALn6CARqj4BeFOizYAdBG4AbFbgAsAJnwsA9HsQASAKIAPAA6poJihTgUuvRAygURrijDABzRDLRMHCVVdW1dIA)

# Predicate Functions

https://flow.org/en/docs/types/functions/#toc-predicate-functions

```javascript
function truthy(a, b): boolean %checks {
  return !!a && !!b;
}
```
そもそも `%checks`なぞTypeScriptにない。
TypeScriptでの解決方法は浮かばず。

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=function%20truthy(a%2C%20b)%3A%20boolean%20%25checks%20%7B%0A%20%20return%20!!a%20%26%26%20!!b%3B%0A%7D)
* [Flowで確認](https://flow.org/try/#0DYUwLgBAZg9jEF4IBYBMBuAUJgllCAFALICGYAFgHQBOJAdgCYwC2BAlG9HIhGNQK4gseQqQo16TVhy7wkAInIhgwGPKyZQkHAGcA8nRB6oALgh1+zAEYhqEAD4QrcUPQcQdfHHQDmPWDDoEAD0wRAA6jDUANY6AIRAA)

# Unsealed Object

```javascript
// @flow
var obj = {};

obj.foo = 1;       // Works!
obj.bar = true;    // Works!
obj.baz = 'three'; // Works!
```

これも同じようにする方法がわからず。すべてのkeyとその型を書く以外の方法がわからなかった。

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Avar%20obj%20%3D%20%7B%7D%3B%0A%0Aobj.foo%20%3D%201%3B%20%20%20%20%20%20%20%2F%2F%20Works!%0Aobj.bar%20%3D%20true%3B%20%20%20%20%2F%2F%20Works!%0Aobj.baz%20%3D%20'three'%3B%20%2F%2F%20Works!)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQA3AhgJ1LARgK1ALygDeAvgNyKI64B0ksshoAjOaB56CKAOqzoA1gGcAhNTy1sGZgBd0AVwCm7Tj35CxEutIBezAOSyAFuiVKD7dQJGigA)

# Exact Object

https://flow.org/en/docs/types/objects/#toc-exact-object-types

```javascript
// @flow
var foo: {| foo: string |} = { foo: "Hello", bar: "World!" }; // Error!
```
TypeScriptには無い文法だが、`interface`を使うか

```javascript
// @flow
interface Hoge { foo: string }
var foo: Hoge = { foo: "Hello", bar: "World!" }; // Error!
```

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Avar%20foo%3A%20%7B%7C%20foo%3A%20string%20%7C%7D%20%3D%20%7B%20foo%3A%20%22Hello%22%2C%20bar%3A%20%22World!%22%20%7D%3B%20%2F%2F%20Error!)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQA3AhgJ1JWsBcoBvAHyx3wGcAXdASwDsBzUIgX1AF5DS9QAiACQCm0OLwA0oAEYZ8vAOqx00ACYBCXqBYBuUCFABRdOkWqgA)

# Objects as maps

https://flow.org/en/docs/types/objects/#toc-objects-as-maps

```javascript
// @flow
var o: { [string]: number } = {};
o["foo"] = 0;
o["bar"] = 1;
var foo: number = o["foo"];
```

TypeScriptは文法が違う。labelをつけてあげればよい。labelをつけてもFlowでは動作する。

```javascript
// @flow
var o: { [key: string]: number } = {};
o["foo"] = 0;
o["bar"] = 1;
var foo: number = o["foo"];
```

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Avar%20o%3A%20%7B%20%5Bstring%5D%3A%20number%20%7D%20%3D%20%7B%7D%3B%0Ao%5B%22foo%22%5D%20%3D%200%3B%0Ao%5B%22bar%22%5D%20%3D%201%3B%0Avar%20foo%3A%20number%20%3D%20o%5B%22foo%22%5D%3B)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQA3AhgJ1LAXKA3qANoDOALugJYB2A5gLq5UCuAtgEYCmmAvqALz5uAbkSxCAIkixY4uv1AAGEWPFsMs+QEYRaTFJyhm7LvJX7ZQoA)


# Tuple type

https://flow.org/en/docs/types/tuples/

```javascript

// @flow
let tuple: [number, boolean, string] = [1, true, "three"];

let none: void = tuple[3]; // error
```

TypeScriptでは別の要因でエラーになる。tuple[3]の利用にはエラーがでない。

```javascript

// @flow
let tuple: [number, boolean, string] = [1, true, "three"];

let none: string | number | boolean = tuple[3]; // error
```

これだとエラーにならないので、Tupleというより配列として認識している。

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Alet%20tuple%3A%20%5Bnumber%2C%20boolean%2C%20string%5D%20%3D%20%5B1%2C%20true%2C%20%22three%22%5D%3B%0A%0Alet%20none%3A%20void%20%3D%20tuple%5B3%5D%3B%20%2F%2F%20error)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQ0CmAXUaCuAHVAuUAbQDssBbAIxQCcAaUS2WVAQxIYGc0aBLEgOYBdUAF5iARgY8sKBgCI0ACxooU8oQG5EydKBKwSKQgDdYvACZjMuVEQDMWoA)


## strictly enforced tuple length arity

https://flow.org/en/docs/types/tuples/#toc-strictly-enforced-tuple-length-arity

```javascript
// @flow
let tuple: [number, number] = [1, 2];
// $ExpectError
let array: Array<number>    = tuple; // Error!
```

TypeScriptではエラーにならない。tupleではなく配列として扱われるため。

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Alet%20tuple%3A%20%5Bnumber%2C%20number%5D%20%3D%20%5B1%2C%202%5D%3B%0A%2F%2F%20%24ExpectError%0Alet%20array%3A%20Array%3Cnumber%3E%20%20%20%20%3D%20tuple%3B%20%2F%2F%20Error!)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQ0CmAXUaCuAHVAuUAbQDssBbAIxQCcAaUMq2gXVAF5iBGBgJhYDciEKAAkAUQAeOFAGM04mjVg1k6UAEMlGgJ6EAgtp0AeJtRoA+UNY6ZcqAaBGLlNAIRA)


```javascript
// @flow
let tuple: [number, number] = [1, 2];
tuple.join(', '); // Works!
// $ExpectError
tuple.push(3);    // Error!
```

これも同様。

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Alet%20tuple%3A%20%5Bnumber%2C%20number%5D%20%3D%20%5B1%2C%202%5D%3B%0Atuple.join('%2C%20')%3B%20%2F%2F%20Works!%0A%2F%2F%20%24ExpectError%0Atuple.push(3)%3B%20%20%20%20%2F%2F%20Error!)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQ0CmAXUaCuAHVAuUAbQDssBbAIxQCcAaUMq2gXVAF5iBGBgJhYDcibHhQA6AFawAliQAUAcgYKAlANAhQAdVg0A1gGcAhIk0ASAKIAPHCgDGaCzRq7huVGJxYDACzkBmNVBgjTAnFxojIA)

# Opaque Type Aliases

```js
opaque type ID = string;
```

TypeScriptは対応していない。がんばれば似たようなことはできるはず。

# Interface Types

https://flow.org/en/docs/types/interfaces/

```js
// @flow
class Foo {
  serialize() { return '[Foo]'; }
}

class Bar {
  serialize() { return '[Bar]'; }
}

// $ExpectError
const foo: Foo = new Bar(); // Error!
```

TypeScriptではエラーにならない。
構造的部分型になるため。Flowでは別の型として扱われる。
根本的な思想の違いと考えられる。

Flowでやるなら共通インターフェイスを用意する

```javascript
// @flow
interface Base {
  serialize(): string;
}

class Foo {
  serialize() { return '[Foo]'; }
}

class Bar {
  serialize() { return '[Bar]'; }
}

// $ExpectError
const foo: Base = new Bar(); // Error!
foo.serialize();
```

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Aclass%20Foo%20%7B%0A%20%20serialize()%20%7B%20return%20'%5BFoo%5D'%3B%20%7D%0A%7D%0A%0Aclass%20Bar%20%7B%0A%20%20serialize()%20%7B%20return%20'%5BBar%5D'%3B%20%7D%0A%7D%0A%0A%2F%2F%20%24ExpectError%0Aconst%20foo%3A%20Foo%20%3D%20new%20Bar()%3B%20%2F%2F%20Error!)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQBjaBDAzh0AxWtQBvRUUDAUwCcBLNaagL3IAoBKI0S8gFwFdKAdqADkAbTywAusIDcoAL6JFKdFlAAhNJSIkyVWvSZsOXPoJGjNlaXMXKQoACQBRAB4AHcsm7PKlWJQosAIY3KCQ+ABcuPigALygAuTwGlpscg6+-pQAhEA)


## read only and write only

https://flow.org/en/docs/types/interfaces/#toc-interface-property-variance-read-only-and-write-only

```javascript
interface MyInterface {
  +covariant: number;     // read-only
  -contravariant: number; // write-only
}
```

TypeScriptではreadonlyの書き方は違うし、writeonlyはやり方しらない。

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=interface%20MyInterface%20%7B%0A%20%20%2Bcovariant%3A%20number%3B%20%20%20%20%20%2F%2F%20read-only%0A%20%20-contravariant%3A%20number%3B%20%2F%2F%20write-only%0A%7D)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQBjaBDAzh0AxWtQBvRUUDAUwCcBLNaagL3IAoBKI0S8gFwFdKAdqADkAbTywAusIDcoAL6JFKdFlAAhNJSIkyVWvSZsOXPoJGjNlaXMXKQoACQBRAB4AHcsm7PKlWJQosAIY3KCQ+ABcuPigALygAuTwGlpscg6+-pQAhEA)

# Generic Type

https://flow.org/en/docs/types/generics/

```javascript
// @flow

type IdentityWrapper = {
  func<T>(T): T
}

function identity(value) {
  return value;
}

function genericIdentity<T>(value: T): T {
  return value;
}

// $ExpectError
const bad: IdentityWrapper = { func: identity }; // Error!
const good: IdentityWrapper = { func: genericIdentity }; // Works!
```

TypeScriptだとidentityが暗黙のanyでエラーになってしまう。
下記のコードで代用してみたが、badはエラーにならなかった。

```typescript

type IdentityWrapper = {
  func<T>(t: T): T
}

function identity(value: any): any {
  return value;
}

function genericIdentity<T>(value: T): T {
  return value;
}

// $ExpectError
const bad: IdentityWrapper = { func: identity }; // Error!
const good: IdentityWrapper = { func: genericIdentity }; // Works!
```



* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0A%0Atype%20IdentityWrapper%20%3D%20%7B%0A%20%20func%3CT%3E(T)%3A%20T%0A%7D%0A%0Afunction%20identity(value)%20%7B%0A%20%20return%20value%3B%0A%7D%0A%0Afunction%20genericIdentity%3CT%3E(value%3A%20T)%3A%20T%20%7B%0A%20%20return%20value%3B%0A%7D%0A%0A%2F%2F%20%24ExpectError%0Aconst%20bad%3A%20IdentityWrapper%20%3D%20%7B%20func%3A%20identity%20%7D%3B%20%2F%2F%20Error!%0Aconst%20good%3A%20IdentityWrapper%20%3D%20%7B%20func%3A%20genericIdentity%20%7D%3B%20%2F%2F%20Works!)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQiAuBPADgU1ASQCZYB2KAlugOoBOAhhtlaALygDeiookArkQMYAeACoA+ABRCAlAC5QQxAF9kPfmVhFQpQiXJoxANxrRuWSWw6gqWFNyobDxrAG5Fy3nzUaA5sSxVSfATEZOjC4g4mslJR5pxWNnagEc6uiCCgACQAogAe2B5ZVFSwVIh86gDOKKAARjT4skE6lLT0fsxsXO6yWsG6oApOoOmFxVQAhGWV1V6wsA142iFo1HQMHaxd-LI+RH4BTcsDQ+kUJQDWFeNAA)

## 型の制約

```javascript

// @flow
function logFoo<T: { foo: string }>(obj: T): T {
  console.log(obj.foo); // Works!
  return obj;
}

logFoo({ foo: 'foo', bar: 'bar' });  // Works!
// $ExpectError
logFoo({ bar: 'bar' }); // Error!
```

TypeScriptだと制約の付け方が違う。
`extends`で指定できる

```javascript
// @flow
function logFoo<T extends { foo: string } >(obj: T): T {
  console.log(obj.foo); // Works!
  return obj;
}

logFoo({ foo: 'foo', bar: 'bar' });  // Works!
// $ExpectError
logFoo({ bar: 'bar' }); // Error!
```

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%0A%2F%2F%20%40flow%0Afunction%20logFoo%3CT%3A%20%7B%20foo%3A%20string%20%7D%3E(obj%3A%20T)%3A%20T%20%7B%0A%20%20console.log(obj.foo)%3B%20%2F%2F%20Works!%0A%20%20return%20obj%3B%0A%7D%0A%0AlogFoo(%7B%20foo%3A%20'foo'%2C%20bar%3A%20'bar'%20%7D)%3B%20%20%2F%2F%20Works!%0A%2F%2F%20%24ExpectError%0AlogFoo(%7B%20bar%3A%20'bar'%20%7D)%3B%20%2F%2F%20Error!)
* [Flow](https://flow.org/try/#0PTAEAEDMBsHsHcBQkCuA7AxgFwJazaHAOYBissAPACoBcoA3qJOXQM5YBOOaRoAvgD4AFLABGAKzpUAlFIaJQoDPlaxoAUwB0xERM3NY0gNygQoAOqwOAa1YBCBaA7qsKDgTHijiPokTEyWCFGAzoAcgMwgBpQUQBDDnD4jjD+Y0UzSxt7RDMAEgBRAA8AB3VsAo4OK39YUnJg2ISkhNS+dLNK6o47IA)

## リテラル値のあるオブジェクトのUnion Type

```javascript
// @flow
type Success = { success: true, value: boolean };
type Failed  = { success: false, error: string };

type Response = Success | Failed;

function handleResponse(response: Response) {
  if (response.success) {
    var value: boolean = response.value; // Works!
  } else {
    var error: string = response.error; // Works!
  }
}
```

この辺はオブジェクト型の問題なのでどうしようもない。

以下のようにしてもだめだった。

```javascript
// @flow
interface Success {
    success: true,
    value: boolean,
}

interface Failed {
    success: false,
    error: string,
}

type Response_ = Success | Failed;

function handleResponse(response: Response_) {
  if (response.success) {
    var value: boolean = response.value; // Works!
  } else {
    var error: string = response.error; // Works!
  }
}
```

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Atype%20Success%20%3D%20%7B%20success%3A%20true%2C%20value%3A%20boolean%20%7D%3B%0Atype%20Failed%20%20%3D%20%7B%20success%3A%20false%2C%20error%3A%20string%20%7D%3B%0A%0Atype%20Response%20%3D%20Success%20%7C%20Failed%3B%0A%0Afunction%20handleResponse(response%3A%20Response)%20%7B%0A%20%20if%20(response.success)%20%7B%0A%20%20%20%20var%20value%3A%20boolean%20%3D%20response.value%3B%20%2F%2F%20Works!%0A%20%20%7D%20else%20%7B%0A%20%20%20%20var%20error%3A%20string%20%3D%20response.error%3B%20%2F%2F%20Works!%0A%20%20%7D%0A%7D)
* [Flow](https://flow.org/try/#0PTAEAEDMBsHsHcBQAXAngBwKagMoFcBjAzAZxNAF5QBvUEw4sgLlGQCc9MAaUANwENonFgCNYsaJn4A7UAF8A3CgzYAYvwCWkgCahKNOg1IkWkQSW6hMbNrDYsS7DdIDm8pcqygASqXSxpC318ImNQAB9QdS1MbQ9IPGkCZA0A0AALGW1JXxJ-QMwACjY-AIsWXPyLAEoaRD0NSFBi0oKAOnpQslrqer0+fjYBoUxRcUkZfRK8ssw2gRGFUBBQAHU7AGsSAEI+uStoIN7+gaHrW3s6J1cp1os287sllfW2Ld29OUQ5IA)

# typeof

## typeof type syntax

https://flow.org/en/docs/types/typeof/#toc-typeof-type-syntax

```javascript
// @flow
let num1 = 42;
let num2: typeof num1 = 3.14;     // Works!
// $ExpectError
let num3: typeof num1 = 'world';  // Error!

let bool1 = true;
let bool2: typeof bool1 = false;  // Works!
// $ExpectError
let bool3: typeof bool1 = 42;     // Error!

let str1 = 'hello';
let str2: typeof str1 = 'world'; // Works!
// $ExpectError
let str3: typeof str1 = false;   // Error!
```

`let bool2: typeof bool1 = false;  // Works!`がエラーになる。 bool1 の型はtrueと認識してしまう。どうしようもなさそう。

* [TypeScriptで確認](https://www.typescriptlang.org/play/index.html#src=%2F%2F%20%40flow%0Alet%20num1%20%3D%2042%3B%0Alet%20num2%3A%20typeof%20num1%20%3D%203.14%3B%20%20%20%20%20%2F%2F%20Works!%0A%2F%2F%20%24ExpectError%0Alet%20num3%3A%20typeof%20num1%20%3D%20'world'%3B%20%20%2F%2F%20Error!%0A%0Alet%20bool1%20%3D%20true%3B%0Alet%20bool2%3A%20typeof%20bool1%20%3D%20false%3B%20%20%2F%2F%20Works!%0A%2F%2F%20%24ExpectError%0Alet%20bool3%3A%20typeof%20bool1%20%3D%2042%3B%20%20%20%20%20%2F%2F%20Error!%0A%0Alet%20str1%20%3D%20'hello'%3B%0Alet%20str2%3A%20typeof%20str1%20%3D%20'world'%3B%20%2F%2F%20Works!%0A%2F%2F%20%24ExpectError%0Alet%20str3%3A%20typeof%20str1%20%3D%20false%3B%20%20%20%2F%2F%20Error!)
* [Flowで確認](https://flow.org/try/#0PTAEAEDMBsHsHcBQ0CmAXUA7ArgWwIygC8oALAEwDcy6We5AXKGgJ4AOKskdBxoAzADp8pSqHHiQoAOqwATgGsAzgEJEUgCQBRAB4cAxmi1y58mhhy5+TVhy49CJAOTx50ACZOxoKcdNy1c1AAI1hYaEdmOWwUalQMUPDGZnZObkSIvkgAQ2glWMkwWUVVdTBtPRRDPzN4kLDoaxS7dIbIim8JXxN5QLqlNDlIpwALFGg4LyCBuWTbNNAZ4dc5Dy8fIvllNU1dAyMeuWnBpvn7Jazc-M7u-xUgA)

## Typeof inherits behaviors of other types

https://flow.org/en/docs/types/typeof/#toc-typeof-inherits-behaviors-of-other-types

```javascript

// @flow
class MyClass {
  method(val: number) { /* ... */ }
}

class YourClass {
  method(val: number) { /* ... */ }
}

// $ExpectError
let test1: typeof MyClass = YourClass; // Error!
let test2: typeof MyClass = MyClass;   // Works!
```

これまでの傾向からわかってるが一応。TypeScriptではエラーにならない。

# Type Cast

https://flow.org/en/docs/types/casting/#toc-type-cast-expression-syntax

```javascript
(1: number)
```

TypeScriptだとエラーになった。文法の違い。

```typescript
1 as number
```

と書けばいいはず。

# Utility Type

TypeScriptは全滅するはず。省略。

# Module Types

PlayGroundでは再現する方法がうかばないので、省略