TypeScript Handbook を読む (1. Basic Types)

そろそろ TypeScript をきちんと勉強するかー、ということで [公式ページ](https://www.typescriptlang.org/) の [Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html) を読み進めていった読書(?)メモ。
~~バージョンとしては 2.2 になるのかな？~~ 随時更新中
公式ページの適当翻訳メモなので、間違いがあってもご了承ください。

1. Basic Types (今ココ)
1. [Variable Declarations](http://qiita.com/murank/items/913f1c1e4e725047436c)
1. [Interfaces](http://qiita.com/murank/items/553276c3dc2eec9bfe47)
1. [Classes](http://qiita.com/murank/items/7e8f15225bc8259e9bf3)
1. [Functions](http://qiita.com/murank/items/e310ce68ed5a0058d42d)
1. [Generics](http://qiita.com/murank/items/144b686d34fd433a97a3)
1. [Enums](http://qiita.com/murank/items/cc487562b21bae3728ba)
1. [Type Inference](http://qiita.com/murank/items/e67ad7426020321228e9)
1. [Type Compatibility](http://qiita.com/murank/items/606efb0615294a6826e3)
1. [Advanced Types](http://qiita.com/murank/items/bc1776efbecbd2120d94)
1. [Symbols](http://qiita.com/murank/items/04b3b31caa677750f240)
1. [Iterators and Generators](http://qiita.com/murank/items/7ceec53dde886f31a682)
1. [Modules](http://qiita.com/murank/items/0fc4e059be8ea5e1c274)
1. [Namespaces](http://qiita.com/murank/items/0dfad4a0bb91aaa6c97b)
1. [Namespaces and Modules](http://qiita.com/murank/items/0be1978a3515fc76e7ba)
1. [Module Resolution](http://qiita.com/murank/items/5f11466474d49498bbd5)
1. [Declaration Merging](http://qiita.com/murank/items/ec90ba04edab1ea3718e)
1. [JSX](http://qiita.com/murank/items/90164aa9a3bed3c49a80)
1. [Decorators](https://qiita.com/murank/items/580e34883e0832ca7aed)
1. [Mixins](https://qiita.com/murank/items/e77ad8359ed1fd82822d)
1. [Triple-Slash Directives](https://qiita.com/murank/items/faff57883338ebdeda12)
1. [Type Checking JavaScript Files](https://qiita.com/murank/items/588eaddfe8af59914658)


# Basic Types
[原文](https://www.typescriptlang.org/docs/handbook/basic-types.html)

## Boolean
boolean 型あります。

```ts:TypeScript
let isDone: boolean = false;
```
```js:JavaScript
var isDone = false;
```

## Number
数値はすべて浮動小数点として扱います。
16 進数、10 進数に加えて、8 進数、2 進数もサポートしてます。
>8 進数、2 進数サポートはすごいけど、使いドコロあるんだろうか…

```ts:TypeScript
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
```
```js:JavaScript
var decimal = 6;
var hex = 0xf00d;
var binary = 10;
var octal = 484;
```

## String
文字列はダブルクォート(`"`)またはシングルクォート(`'`)で囲みます。

```ts:TypeScript
let color: string = "blue";
color = 'red';
```
```js:JavaScript
var color = "blue";
color = 'red';
```

バッククォート(`` ` ``)で囲んだ文字列には `${　expr　}` で変数・式を埋め込めます。
>`${...}` の中は式として評価されるので、 `${` `}` 前後の空白はあってもなくても問題ない。 

```ts:TypeScript
let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ fullName }.

I'll be ${ age + 1 } years old next month.`
```
```js:JavaScript
var fullName = "Bob Bobbington";
var age = 37;
var sentence = "Hello, my name is " + fullName + ".\n\nI'll be " + (age + 1) + " years old next month.";
```

>これは便利だ。
>しかも文字列中の改行は自動的に \n に置き換えてくれてる。

## Array
配列は以下の 2 通りの宣言方法をサポートしてます。
>配列を組み込み型と考えるか、オブジェクトと考えるかで好みが分かれそう。
>もっとも、大事なことは表記を統一することだね。

```ts:TypeScript
let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];
```
```js:JavaScript
var list1 = [1, 2, 3];
var list2 = [1, 2, 3];
```

## Tuple
指定した型の組のことを Tuple と呼びます。

```ts:TypeScript
// 宣言
let x: [string, number];
// 初期化
x = ["hello", 10]; // OK
// 初期化 (間違い)
x = [10, "hello"]; // エラー
```
```js:JavaScript
// 宣言
var x;
// 初期化
x = ["hello", 10]; // OK
// 初期化 (間違い)
x = [10, "hello"]; // エラー
```

各要素にアクセスするときはインデックスでアクセスします。

```ts:TypeScript
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // エラー。 2 番目の要素は 'number' なので substr は使えない。
```

範囲外の要素にアクセスした場合、自動的に共用型として扱います。

```ts:TypeScript
x[3] = "world"; // OK。 'string' は 'string | number' 型に代入可能。

console.log(x[5].toString()); // OK。 'string' と 'number' 両方にあるメソッドは呼び出し可。

x[6] = true; // エラー。 'boolean' は 'string | number' 型には代入できない。
```

## Enum
TypeScript は Enum をサポートしてます。
>コンパイル後のコードがすごい…

```ts:TypeScript
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
```
```js:JavaScript
var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Green"] = 1] = "Green";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
;
var c = Color.Green;
```

Enum はデフォルトでは 0 からナンバリングされますが、好きな数字からナンバリングすることも可能ですし、

```ts:TypeScript
enum Color {Red = 1, Green, Blue};
let c: Color = Color.Green;
```
```js:JavaScript
var Color;
(function (Color) {
    Color[Color["Red"] = 1] = "Red";
    Color[Color["Green"] = 2] = "Green";
    Color[Color["Blue"] = 3] = "Blue";
})(Color || (Color = {}));
;
var c = Color.Green;
```

すべて自分でナンバリングすることも可能です。

```ts:TypeScript
enum Color {Red = 1, Green = 2, Blue = 4};
let c: Color = Color.Green;
```
```js:JavaScript
var Color;
(function (Color) {
    Color[Color["Red"] = 1] = "Red";
    Color[Color["Green"] = 2] = "Green";
    Color[Color["Blue"] = 4] = "Blue";
})(Color || (Color = {}));
;
var c = Color.Green;
```

インデックスから Enum の要素を取得することも可能です。

```ts:TypeScript
enum Color {Red = 1, Green, Blue};
let colorName: string = Color[2];

console.log(colorName); // 上の Color[2] に対応する値である 'Green' を表示する
```
```js:JavaScript
var Color;
(function (Color) {
    Color[Color["Red"] = 1] = "Red";
    Color[Color["Green"] = 2] = "Green";
    Color[Color["Blue"] = 3] = "Blue";
})(Color || (Color = {}));
;
var colorName = Color[2];
console.log(colorName); // 上の Color[2] に対応する値である 'Green' を表示する
```

## Any
Any 型を使えば型チェックをバイパスすることができます。

```ts:TypeScript
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // 今度は boolean
```
```js:JavaScript
var notSure = 4;
notSure = "maybe a string instead";
notSure = false; // 今度は boolean
```

Object 型でも似たようなことができますが、任意の型を代入できるだけで、その型のメソッドを呼ぶことはできません。
>Object 型なんだから、Object 型で宣言されているメソッドしか呼べないのは当たり前だね。

```ts:TypeScript
let notSure: any = 4;
notSure.ifItExists(); // OK。 実行時には ifItExists メソッドが存在するはず
notSure.toFixed(); // OK。 toFixed メソッドは存在する (けど、コンパイル時チェックはしない)

let prettySure: Object = 4;
prettySure.toFixed(); // エラー。 toFixed メソッドは Object 型には存在しない。
```

Any 型は他の型の一部としても使えます。

```ts:TypeScript
let list: any[] = [1, true, "free"]; // 任意の型を含められる
list[1] = 100;
```
```js:JavaScript
var list = [1, true, "free"]; // 任意の型を含められる
list[1] = 100;
```

## Void
Void は型がないことを表すもので、値を返さない関数の戻り値でよく使います。

```ts:TypeScript
function warnUser(): void {
    console.log("This is my warning message");
}
```
```js:JavaScript
function warnUser() {
    console.log("This is my warning message");
}
```

Void 型には `undefined` か `null` しか代入できません。

```ts:TypeScript
let unusable: void = undefined;
```

## Null と Undefined
Null 型と Undefined 型にはそれぞれの値しか代入できません。

```ts:TypeScript
let u: undefined = undefined;
let n: null = null;
```

デフォルトでは `undefined`、`null` は任意の型に代入することができますが、`--strictNullChecks` フラグを指定した場合、 Void 型かそれぞれの型にしか代入できなくなります。
その状態で `undefined`、`null` の代入を許可したい場合は共用型 (例: `'string | null | undefined'`) を使います。
>公式ページでは `--strictNullChecks` の使用を推奨しているので、なるべく使った方が良さそう。


## Never
Never 型は値を返さないことを表します。
>これまた使いドコロが難しそうな…

```ts:TypeScript
// 例外をスローするのでメソッドの最後まで絶対に到達しない
function error(message: string): never {
    throw new Error(message);
}

// Never 型を return するなら、そのメソッドの戻り値も Never 型になる
function fail() : never {
    return error("Something failed");
}

// 無限ループするのでメソッドの最後まで絶対に到達しない
function infiniteLoop(): never {
    while (true) {
    }
}
```

## Object
`object` は非プリミティブ型、つまり `number`、`string`、`boolean`、`symbol`、`null`、`undefined` 以外の型を表す型です。

`object` 型を使用すると `Object.create` のような API をより分かりやすく記述することができます。

```ts:TypeScript
declarefunctioncreate(o: object | null): void;

create({ prop: 0 }); // OK
create(null); // OK

create(42); // エラー
create("string"); // エラー
create(false); // エラー
create(undefined); // エラー
```

## Type assertions
キャストは以下の 2 通りの表記をサポートしてます。
ただし、JSX を使用する場合、`as` 形式の表記のみ使用可能です。

```ts:TypeScript
let someValue: any = "this is a string";

let strLength1: number = (<string>someValue).length;
let strLength2: number = (someValue as string).length;
```
```js:JavaScript
var someValue = "this is a string";

var strLength1 = someValue.length;
var strLength2 = someValue.length;
```