TypeScript / Swift 比較表（随時更新）

仕事で TypeScript、趣味で Swift を書いている自分用の比較表です。TypeScript は JavaScript や ES6 なども含みます。随時更新します。編集リクエスト大歓迎です。

### 定数・変数

```swift:Swift
let i = 0
var a = "a"
```

```typescript:TypeScript
const i = 0;
let a = "a";
```

### 基本的な型

| Swift       | TypeScript   | Note             |
|-------------|--------------|------------------|
| `Int`       | `number`     |                  |
| `Float`     | `number`     |                  |
| `Double`    | `number`     |                  |
| -           | `bigint`     |                  |
| `Bool`      | `boolean`    |                  |
| `String`    | `string`     |                  |
| -           | `symbol`     |                  |
| `Array`     | `Array`      |                  |
| `Dictionary`| `Object`     |                  |
| `nil`       | `null`       |                  |
| -           | `undefined`  |                  |
| `Void`      | `void`       |                  |
| `Any`       | `unknown`    |                  |

### 文字列補間

```swift:Swift
let n = 10
"\(n) times." // 10 times.
```

```typescript:TypeScript
const n = 10;
`${n} times.` // 10 times.
```

### enum （列挙型）

```swift:Swift
enum Fruit: String {
  case Orange = "🍊"
  case Apple = "🍎"
  case Banana = "🍌"
}
print(Fruit.Orange.rawValue) // 🍊
```

```typescript:TypeScript
enum Fruit {
  Orange = "🍊",
  Apple = "🍎",
  Banana = "🍌",
}
console.log(Fruit.Orange); // 🍊
```

### Array（配列）

#### 範囲外のアクセス

```swift:Swift
let i = 10
let numbers = [1, 2, 3]

print(numbers[i]) // EXC_BAD_INSTRUCTION

if i < numbers.count {
  ...
}
```

```typescript:TypeScript
const i = 10;
const numbers = [1, 2, 3];

console.log(numbers[i]); // undefined

if numbers[i] !== undefined {
   ...
}
```

Swift も `if let` とかでチェックできるといいのだけど...

* [indexがArrayの範囲内かチェックする色々な書き方 - Qiita](https://qiita.com/shtnkgm/items/f02553cb6bb16a59d8fe)

### Object / Dictionary

#### 基本

```swift:Swift
var dict: [String: Any] = [:]
dict["abc"] = 123
print(dict["abc"] ?? "No value")
```

```typescript:TypeScript
let obj: { [_: string]: any } = {};
obj['abc'] = 123;
console.log(obj['abc'] || 'No value');
```

#### 存在確認

```swift:Swift
var fruits = [
  "apple": "🍎",
  "orange": "🍊"
]
if let apple = fruits["apple"] {
  print(apple)
}
```

キーが存在しない場合は `nil` を返す。

```typescript:TypeScript
const fruits = {
  apple: "🍎",
  orange: "🍊"
};
if ('apple' in fruits) {
  console.log(fruits['apple']);    
}
```

キーが存在しない場合は `undefined` を返す。

#### マージ（新しい方で上書き）

```swift:Swift
var a = ["apple": "🍎",
         "orange": "🍊"]
let b = ["apple": "🍏",
         "banana": "🍌"]
let merged = a.merging(b) { _, new in new }
// ["apple": "🍏", "banana": "🍌", "orange": "🍊"]
```

```typescript:TypeScript
const a = {
  apple: "🍎",
  orange: "🍊"
}
const b = {
  "apple": "🍏",
  "banana": "🍌"
}
const merged = Object.assign({}, a, b)
// {apple: "🍏", orange: "🍊", banana: "🍌"}
```

どっちも面倒臭い。どっちも shallow マージ。

### struct （構造体）

```swift:Swift
struct Person {
  var name: String
  var age: Int
};

let person = Person(name: "Taro", age: 20)
```

```typescript:TypeScript
type Person = {
  name: string;
  age: number;
}

const person: Person = {
  name: "Taro",
  age: 20
};
```

TypeScript の `type` を構造体とみなしていいのかどうかはわからない...

### class （クラス）

```swift:Swift
class Person {
  // メンバ変数
  var word: String
  // コンストラクタ（イニシャライザ）
  init(word: String) {
    self.word = word
  }
  // デストラクタ（例はイマイチ）
  deinit {
    self.word = "Bye..."
  }
  // メソッド
  func say() -> String {
    return self.word
  }
}

let person = Person(word: "Hello!")
person.say()
```

```typescript:TypeScript
class Person {
  // メンバ変数
  word: string;
  // コンストラクタ（イニシャライザ）
  constructor(word: string) {
    this.word = word;
  }
  // メソッド
  say() {
    return this.word;
  }
}

const person = new Person("Hello!");
person.say();
```

TypeScript にはデストラクタはない模様。

### タイマー

```swift:Swift
let timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { timer in
  print("Fired")
}

timer.invalidate() // Stop the timer
```

```typescript:TypeScript
// 繰り返しの時は、setInterval() を使う
const timer = setTimeout(() => {
  console.log("Fired");
}, 3000);

clearTimeout(timer); // Stop the timer
```

### ToDo

* プリミティブ型
* any / void
* function / closure
* getter / setter
* キャスト
* ループ
* while / do while
* if / switch
* Array / Set
* .count, .length
* 比較演算子
* &&, ||, ??
* 三項演算子
* 分割代入
* スプレッド構文
* 可変長引数
* protocol
* interface
* extension
* typeof / instanceof / in / of
* optional
* タプル
* guard
* if let = ...
* range
* ヒアドキュメント
* 長さ（文字列、配列）
* Error
* マクロ関連
* 環境変数
* _
* subscript
* undefined
* Never
* union
* ジェネリクス
* typealias
* some / where
* weak / unowned
* lazy
* async / await
* yield
* public / private / etc...
* static
* print / console.log
* module / namespace
* コメントアウト

### Reference

* [Swift is like TypeScript](https://alhazmy13.github.io/swift-is-like-typescript/)
* [The Basics — The Swift Programming Language (Swift 5.1)](https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html)
* [Handbook - The TypeScript language reference](http://www.typescriptlang.org/docs/handbook/basic-types.html)
* [TypeScriptの型入門 - Qiita](https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a)