Skip to content

Commit 774ae2c

Browse files
authored
[typescript/zh-tw] translate (#5142)
1 parent 7678771 commit 774ae2c

File tree

1 file changed

+286
-0
lines changed

1 file changed

+286
-0
lines changed

zh-tw/typescript-tw.html.markdown

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
---
2+
language: TypeScript
3+
contributors:
4+
- ["Philippe Vlérick", "https://github.com/pvlerick"]
5+
- ["Kiwimoe", "https://github.com/kiwimoe"]
6+
translators:
7+
- ["Woody Chang", "https://github.com/kazettique"]
8+
filename: learntypescript-zh-tw.ts
9+
lang: zh-tw
10+
---
11+
12+
TypeScript 是為開發大型 JavaScript 應用程式而設計的語言。它為 JavaScript 導入某些程式語言常見的一些概念,諸如:類別(class)、模組(module)、介面(interface)、泛型(generic type)和靜態型別(static type)。TypeScript 是 JavaScript 的「超集」(superset):意即建立在 JavaScript 的基礎上,所有 JavaScript 語法皆可在 TypeScript 中使用。因此,TypeScript 可以無縫導入到任何 JavaScript 專案中。TypeScript 編譯器最終會編譯成 JavaScript 程式碼。
13+
14+
本文將只專注於 TypeScript 的額外語法,其他請參考 [JavaScript 的指南](/docs/javascript-tw)
15+
16+
要測試 TypeScript 的編譯器,請前往 [Playground](https://www.typescriptlang.org/play),在那裡你可以輸入程式碼,獲得自動完成(autocomplete)功能,並查看編譯過的 JavaScript 程式碼。
17+
18+
```ts
19+
// TS 基本型別有三種
20+
let isDone: boolean = false;
21+
let lines: number = 42;
22+
let name: string = "Anders";
23+
24+
// 當變數有賦值時,也可以省略型別定義
25+
let isDone = false;
26+
let lines = 42;
27+
let name = "Anders";
28+
29+
// 若無法確定型別,則可以定義為 `any`
30+
let notSure: any = 4;
31+
notSure = "maybe a string instead";
32+
notSure = false; // 布林值也屬於 `any` 型別
33+
34+
// 以 `const` 關鍵字定義常數
35+
const numLivesForCat = 9;
36+
numLivesForCat = 1; // 報錯,常數初始化之後,無法指定新值
37+
38+
// 關於集合類型的資料,有型別化陣列(typed array)和泛型陣列(generic array)
39+
let list: number[] = [1, 2, 3];
40+
// 或使用泛型陣列類型
41+
let list: Array<number> = [1, 2, 3];
42+
43+
// 列舉型別:
44+
enum Color { Red, Green, Blue };
45+
let c: Color = Color.Green;
46+
console.log(Color[c]); // "Green"
47+
48+
// `void` 用於函式不回傳任何值的特殊情況
49+
function bigHorribleAlert(): void {
50+
alert("I'm a little annoying box!");
51+
}
52+
53+
// 函式是一等公民,支援 lambda「胖箭頭」 `=>` 語法,並使用型別推斷
54+
55+
// 以下幾種函式寫法是等效的,編譯器會生成相同的 JavaScript 程式碼
56+
// 一般的函式
57+
let f1 = function (i: number): number { return i * i; }
58+
// 自動推斷回傳型別
59+
let f2 = function (i: number) { return i * i; }
60+
// 使用胖箭頭語法
61+
let f3 = (i: number): number => { return i * i; }
62+
// 胖箭頭語法(自動推斷回傳型別)
63+
let f4 = (i: number) => { return i * i; }
64+
// 胖箭頭語法(自動推斷回傳型別、省略函式的括號與 `return` 關鍵字)
65+
let f5 = (i: number) => i * i;
66+
67+
// 函式的參數也可以同時定義多種型別的連集
68+
function f6(i: string | number): void {
69+
console.log("The value was " + i);
70+
}
71+
72+
// 介面是結構化的,任何擁有這些屬性的物件都要符合該介面的定義
73+
interface Person {
74+
name: string;
75+
// 以問號(`?`)來表示選填的屬性
76+
age?: number;
77+
// 當然也可以包含函式
78+
move(): void;
79+
}
80+
81+
// 實作 `Person` 介面的物件
82+
// 可被視為一個 `Person` 物件,因為它具有 `name` 和 `move` 屬性
83+
let p: Person = { name: "Bobby", move: () => { } };
84+
// 包含選填屬性的物件:
85+
let validPerson: Person = { name: "Bobby", age: 42, move: () => { } };
86+
// 此物件非 `Person` 物件,因為 `age` 屬性非數字
87+
let invalidPerson: Person = { name: "Bobby", age: true };
88+
89+
// 介面也可以描述一個函式的型別
90+
interface SearchFunc {
91+
(source: string, subString: string): boolean;
92+
}
93+
// 函式的型別定義著重於各個參數以及回傳值的型別,而函式名稱並不重要
94+
let mySearch: SearchFunc;
95+
mySearch = function (src: string, sub: string) {
96+
return src.search(sub) != -1;
97+
}
98+
99+
// 類別的屬性,其存取權限預設為公開(public)
100+
class Point {
101+
// 定義屬性
102+
x: number;
103+
104+
// 在建構函式種使用 `public`、`private` 關鍵字,會實例化的時候自動生成屬性
105+
// 以此為例,`y` 如同 `x` 定義其屬性,並於實例化時賦值,但寫法更為簡潔,同時支援預設值
106+
constructor(x: number, public y: number = 0) {
107+
this.x = x;
108+
}
109+
110+
// 函式,在類別中,又稱為方法(method)
111+
dist(): number {
112+
return Math.sqrt(this.x * this.x + this.y * this.y);
113+
}
114+
115+
// 靜態成員(static member)
116+
static origin = new Point(0, 0);
117+
}
118+
119+
// 類別可以被明確標記為實作某個介面。
120+
// 任何缺少的屬性或方法都會在編譯時引發錯誤。
121+
class PointPerson implements Person {
122+
name: string
123+
move() {}
124+
}
125+
126+
let p1 = new Point(10, 20);
127+
let p2 = new Point(25); // y 值將預設為 0
128+
129+
// 類別的繼承
130+
class Point3D extends Point {
131+
constructor(x: number, y: number, public z: number = 0) {
132+
super(x, y); // 必須明確呼叫父類別的建構函式,使用 `super` 關鍵字
133+
}
134+
135+
// 複寫父類別的方法
136+
dist(): number {
137+
let d = super.dist();
138+
return Math.sqrt(d * d + this.z * this.z);
139+
}
140+
}
141+
142+
// 模組,以 `.` 語法存取子模組
143+
module Geometry {
144+
export class Square {
145+
constructor(public sideLength: number = 0) {
146+
}
147+
area() {
148+
return Math.pow(this.sideLength, 2);
149+
}
150+
}
151+
}
152+
153+
let s1 = new Geometry.Square(5);
154+
155+
// 引用模組,可以在本地使用別名命名並使用之
156+
import G = Geometry;
157+
158+
let s2 = new G.Square(10);
159+
160+
// 泛用型別,泛型(generic type)
161+
// 在類別使用泛型
162+
class Tuple<T1, T2> {
163+
constructor(public item1: T1, public item2: T2) {
164+
}
165+
}
166+
167+
// 在介面使用泛型
168+
interface Pair<T> {
169+
item1: T;
170+
item2: T;
171+
}
172+
173+
// 在函式使用泛型
174+
let pairToTuple = function <T>(p: Pair<T>) {
175+
return new Tuple(p.item1, p.item2);
176+
};
177+
178+
let tuple = pairToTuple({ item1: "hello", item2: "world" });
179+
180+
// 引用型別定義檔:
181+
/// <reference path="jquery.d.ts" />
182+
183+
// 樣板字串(template string)(使用反引號「`」的字串)
184+
// 以樣板字串進行字串內插(interpolation)
185+
let name = 'Tyrone';
186+
let greeting = `Hi ${name}, how are you?`
187+
// 多行的樣板字串
188+
let multiline = `This is an example
189+
of a multiline string`;
190+
191+
// 唯讀存取子:TypeScript 3.1 的新語法
192+
interface Person {
193+
readonly name: string;
194+
readonly age: number;
195+
}
196+
197+
var p1: Person = { name: "Tyrone", age: 42 };
198+
p1.age = 25; // 錯誤,`p1.age` 為唯讀屬性
199+
200+
var p2 = { name: "John", age: 60 };
201+
var p3: Person = p2; // 正確,`p2` 的唯讀別名
202+
p3.age = 35; // 錯誤,`p3.age` 為唯讀屬性
203+
p2.age = 45; // 正確,但因為 `p3` 參照可 `p2`,因此 `p3.age` 將會被修改
204+
205+
class Car {
206+
readonly make: string;
207+
readonly model: string;
208+
readonly year = 2018;
209+
210+
constructor() {
211+
this.make = "Unknown Make"; // 唯讀屬性在建構函式被允許賦值
212+
this.model = "Unknown Model"; // 唯讀屬性在建構函式被允許賦值
213+
}
214+
}
215+
216+
let numbers: Array<number> = [0, 1, 2, 3, 4];
217+
let moreNumbers: ReadonlyArray<number> = numbers;
218+
moreNumbers[5] = 5; // 錯誤,陣列的成員為唯讀
219+
moreNumbers.push(5); // 錯誤,無 `push` 方法(因為 `push` 方法會改變陣列的值)
220+
moreNumbers.length = 3; // 錯誤,`length` 為唯讀
221+
numbers = moreNumbers; // 錯誤,修改陣列的方法並不存在於唯讀陣列
222+
223+
// 可以使用聯合型別(union type)來定義不同的資料型別
224+
type State =
225+
| { type: "loading" }
226+
| { type: "success", value: number }
227+
| { type: "error", message: string };
228+
229+
declare const state: State;
230+
if (state.type === "success") {
231+
console.log(state.value);
232+
} else if (state.type === "error") {
233+
console.error(state.message);
234+
}
235+
236+
// 樣板實字(template literal)型別
237+
// 可以用來建立複雜的字串型別
238+
type OrderSize = "regular" | "large";
239+
type OrderItem = "Espresso" | "Cappuccino";
240+
type Order = `A ${OrderSize} ${OrderItem}`;
241+
242+
let order1: Order = "A regular Cappuccino";
243+
let order2: Order = "A large Espresso";
244+
let order3: Order = "A small Espresso"; // 錯誤
245+
246+
// 迭代器(iterator)與產生器(generator)
247+
248+
// for..of 陳述式
249+
// 循覽物件的每個成員「值」(value)
250+
let arrayOfAnyType = [1, "string", false];
251+
for (const val of arrayOfAnyType) {
252+
console.log(val); // 1, "string", false
253+
}
254+
255+
let list = [4, 5, 6];
256+
for (const i of list) {
257+
console.log(i); // 4, 5, 6
258+
}
259+
260+
// for..in 陳述式
261+
// 循覽物件的每個成員的「鍵」(key)
262+
for (const i in list) {
263+
console.log(i); // 0, 1, 2
264+
}
265+
266+
// 型別斷言(assertion)
267+
let foo = {} // 建立一個名為 `foo` 的空物件
268+
foo.bar = 123 // 錯誤,`bar` 屬性並不存在於 `{}`
269+
foo.baz = 'hello world' // 錯誤:`baz` 屬性並不存在於 `{}`
270+
271+
// 因為 `foo` 的推斷型別是 `{}`(一個無任何屬性的物件),所以不允許新增 `bar`、`baz` 及其他任何名稱的屬性。然而,通過型別斷言,以下程式碼將能夠通過 TS 的檢查:
272+
interface Foo {
273+
bar: number;
274+
baz: string;
275+
}
276+
277+
let foo = {} as Foo; // 這裡使用型別斷言
278+
foo.bar = 123;
279+
foo.baz = 'hello world'
280+
```
281+
282+
## 延伸閱讀
283+
284+
* [TypeScript官網](https://www.typescriptlang.org/)
285+
* [TypeScript原始碼](https://github.com/microsoft/TypeScript)
286+
* [Learn TypeScript](https://learntypescript.dev/)

0 commit comments

Comments
 (0)