diff --git a/zh-tw/typescript-tw.html.markdown b/zh-tw/typescript-tw.html.markdown
new file mode 100644
index 00000000..ab17c89c
--- /dev/null
+++ b/zh-tw/typescript-tw.html.markdown
@@ -0,0 +1,286 @@
+---
+language: TypeScript
+contributors:
+ - ["Philippe Vlérick", "https://github.com/pvlerick"]
+ - ["Kiwimoe", "https://github.com/kiwimoe"]
+translators:
+ - ["Woody Chang", "https://github.com/kazettique"]
+filename: learntypescript-zh-tw.ts
+lang: zh-tw
+---
+
+TypeScript 是為開發大型 JavaScript 應用程式而設計的語言。TypeScript 為 JavaScript 導入某些程式語言常見的一些概念,諸如:類別、模組、介面、泛型和(可選的)靜態型別。它是 JavaScript 的超集:因此所有 JavaScript 語法都可以使用。TypeScript 程式碼可以無縫導入到任何 JavaScript 專案中。TypeScript 編譯器最終會編譯成 JavaScript 程式碼。
+
+本文將只專注於 TypeScript 的額外語法,其他請參考 [JavaScript 的指南](/docs/javascript-tw)
+
+要測試 TypeScript 的編譯器,請前往 [Playground](https://www.typescriptlang.org/play),在那裡你可以輸入程式碼,獲得自動完成功能,並直接查看生成的 JavaScript 程式碼。
+
+```ts
+// TS 基本型別有三種
+let isDone: boolean = false;
+let lines: number = 42;
+let name: string = "Anders";
+
+// 當變數有賦值時,也可以省略型別定義
+let isDone = false;
+let lines = 42;
+let name = "Anders";
+
+// 若無法確定型別,則可以定義為 `any`
+let notSure: any = 4;
+notSure = "maybe a string instead";
+notSure = false; // 布林值也屬於 `any` 型別
+
+// 以 `const` 關鍵字定義常數
+const numLivesForCat = 9;
+numLivesForCat = 1; // 報錯,常數初始化之後,無法指定新值
+
+// 關於集合類型的資料,有型別化陣列(typed array)和泛型陣列(generic array)
+let list: number[] = [1, 2, 3];
+// 或者使用泛型陣列類型
+let list: Array = [1, 2, 3];
+
+// 關於列舉型別:
+enum Color { Red, Green, Blue };
+let c: Color = Color.Green;
+console.log(Color[c]); // "Green"
+
+// 最後,`void` 用於函式不回傳任何值的特殊情況
+function bigHorribleAlert(): void {
+ alert("I'm a little annoying box!");
+}
+
+// 函式是一等公民,支援 lambda「胖箭頭」語法,並使用型別推斷
+
+// 以下幾種函式寫法是等效的,編譯器會生成相同的 JavaScript
+// 一般的函式
+let f1 = function (i: number): number { return i * i; }
+// 自動推斷回傳型別
+let f2 = function (i: number) { return i * i; }
+// 胖箭頭語法
+let f3 = (i: number): number => { return i * i; }
+// 胖箭頭語法(自動推斷回傳型別)
+let f4 = (i: number) => { return i * i; }
+// 胖箭頭語法(自動推斷回傳型別、省略函式的括號與 `return` 關鍵字)
+let f5 = (i: number) => i * i;
+
+// 函式的參數也可以接受同時多種型別的定義
+function f6(i: string | number): void {
+ console.log("The value was " + i);
+}
+
+// 介面是結構化的,任何擁有這些屬性的物件都符合該介面的定義
+interface Person {
+ name: string;
+ // 以問號(`?`)來表示選填的屬性
+ age?: number;
+ // 當然也可以包含函式
+ move(): void;
+}
+
+// 實作 `Person` 介面的物件
+// 可被視為一個 `Person` 物件,因為它具有 `name` 和 `move` 屬性
+let p: Person = { name: "Bobby", move: () => { } };
+// 包含選填屬性的物件:
+let validPerson: Person = { name: "Bobby", age: 42, move: () => { } };
+// 此物件非 `Person` 物件,因為 `age` 屬性非數字
+let invalidPerson: Person = { name: "Bobby", age: true };
+
+// 介面也可以描述一個函式的型別
+interface SearchFunc {
+ (source: string, subString: string): boolean;
+}
+// 函式的型別定義著重於各個參數以及回傳值的型別,而函式名稱並不重要。
+let mySearch: SearchFunc;
+mySearch = function (src: string, sub: string) {
+ return src.search(sub) != -1;
+}
+
+// 類別的屬性,其存取權限預設為公開(public)
+class Point {
+ // 定義屬性
+ x: number;
+
+ // 在建構函式種使用 `public`、`private` 關鍵字,會實例化的時候自動生成屬性
+ // 以此為例,`y` 如同 `x` 定義其屬性,並於實例化時賦值,但寫法更為簡潔,同時支援預設值
+ constructor(x: number, public y: number = 0) {
+ this.x = x;
+ }
+
+ // 函式(在類別中,又稱為方法)
+ dist(): number {
+ return Math.sqrt(this.x * this.x + this.y * this.y);
+ }
+
+ // 靜態成員(static member)
+ static origin = new Point(0, 0);
+}
+
+// 類別可以被明確標記為實作某個介面。
+// 任何缺少的屬性或方法都會在編譯時引發錯誤。
+class PointPerson implements Person {
+ name: string
+ move() {}
+}
+
+let p1 = new Point(10, 20);
+let p2 = new Point(25); //y will be 0
+
+// 類別的繼承
+class Point3D extends Point {
+ constructor(x: number, y: number, public z: number = 0) {
+ super(x, y); // 必須明確呼叫父類別的建構函式
+ }
+
+ // 複寫父類別的方法
+ dist(): number {
+ let d = super.dist();
+ return Math.sqrt(d * d + this.z * this.z);
+ }
+}
+
+// 模組,以 `.` 語法作為子模組的分隔符
+module Geometry {
+ export class Square {
+ constructor(public sideLength: number = 0) {
+ }
+ area() {
+ return Math.pow(this.sideLength, 2);
+ }
+ }
+}
+
+let s1 = new Geometry.Square(5);
+
+// 引用模組,可以在本地使用別名命名並使用之
+import G = Geometry;
+
+let s2 = new G.Square(10);
+
+// 泛用型別(泛型)
+// 在類別使用泛型
+class Tuple {
+ constructor(public item1: T1, public item2: T2) {
+ }
+}
+
+// 在介面使用泛型
+interface Pair {
+ item1: T;
+ item2: T;
+}
+
+// 以及在函式使用泛型
+let pairToTuple = function (p: Pair) {
+ return new Tuple(p.item1, p.item2);
+};
+
+let tuple = pairToTuple({ item1: "hello", item2: "world" });
+
+// 引用型別定義檔:
+///
+
+// 樣板字串(template string)(使用反引號「`」的字串)
+// 以樣板字串進行字串內插(interpolation)
+let name = 'Tyrone';
+let greeting = `Hi ${name}, how are you?`
+// 多行的樣板字串
+let multiline = `This is an example
+of a multiline string`;
+
+// 唯讀存取子:TypeScript 3.1 的新語法
+interface Person {
+ readonly name: string;
+ readonly age: number;
+}
+
+var p1: Person = { name: "Tyrone", age: 42 };
+p1.age = 25; // 錯誤,`p1.age` 為唯讀屬性
+
+var p2 = { name: "John", age: 60 };
+var p3: Person = p2; // 正確,`p2` 的唯讀別名
+p3.age = 35; // 錯誤,`p3.age` 為唯讀屬性
+p2.age = 45; // 正確,但因為 `p3` 參照可 `p2`,因此 `p3.age` 將會被修改
+
+class Car {
+ readonly make: string;
+ readonly model: string;
+ readonly year = 2018;
+
+ constructor() {
+ this.make = "Unknown Make"; // 唯讀屬性在建構函式被允許賦值
+ this.model = "Unknown Model"; // 唯讀屬性在建構函式被允許賦值
+ }
+}
+
+let numbers: Array = [0, 1, 2, 3, 4];
+let moreNumbers: ReadonlyArray = numbers;
+moreNumbers[5] = 5; // 錯誤,陣列的成員為唯讀
+moreNumbers.push(5); // 錯誤,無 `push` 方法(因為 `push` 方法會改變陣列的值)
+moreNumbers.length = 3; // 錯誤,`length` 為唯讀
+numbers = moreNumbers; // 錯誤,修改陣列的方法並不存在於唯讀陣列
+
+// 可以使用聯合型別(union type)來定義不同的資料型別
+type State =
+ | { type: "loading" }
+ | { type: "success", value: number }
+ | { type: "error", message: string };
+
+declare const state: State;
+if (state.type === "success") {
+ console.log(state.value);
+} else if (state.type === "error") {
+ console.error(state.message);
+}
+
+// 樣板實字(template literal)型別
+// 可以用來建立複雜的字串型別
+type OrderSize = "regular" | "large";
+type OrderItem = "Espresso" | "Cappuccino";
+type Order = `A ${OrderSize} ${OrderItem}`;
+
+let order1: Order = "A regular Cappuccino";
+let order2: Order = "A large Espresso";
+let order3: Order = "A small Espresso"; // 錯誤
+
+// 迭代器(iterator)與產生器(generator)
+
+// for..of 陳述式
+// 循覽物件的每個成員「值」(value)
+let arrayOfAnyType = [1, "string", false];
+for (const val of arrayOfAnyType) {
+ console.log(val); // 1, "string", false
+}
+
+let list = [4, 5, 6];
+for (const i of list) {
+ console.log(i); // 4, 5, 6
+}
+
+// for..in 陳述式
+// 循覽物件的每個成員的「鍵」(key)
+for (const i in list) {
+ console.log(i); // 0, 1, 2
+}
+
+// 型別斷言(assertion)
+let foo = {} // 建立一個名為 `foo` 的空物件
+foo.bar = 123 // 錯誤,`bar` 屬性並不存在於 `{}`
+foo.baz = 'hello world' // 錯誤:`baz` 屬性並不存在於 `{}`
+
+// 因為 `foo` 的推斷型別是 `{}`(一個無任何屬性的物件),所以不允許新增 `bar`、`baz` 及其他任何名稱的屬性。然而,通過型別斷言,以下程式碼將能夠通過 TS 的檢查:
+interface Foo {
+ bar: number;
+ baz: string;
+}
+
+let foo = {} as Foo; // 這裡使用型別斷言
+foo.bar = 123;
+foo.baz = 'hello world'
+```
+
+## 延伸閱讀
+
+* [TypeScript官網](https://www.typescriptlang.org/)
+* [TypeScript原始碼](https://github.com/microsoft/TypeScript)
+* [Learn TypeScript](https://learntypescript.dev/)