Open jing12345678910 opened 2 weeks ago
TypeScript 提供靜態型別檢查功能,幫助開發者在撰寫程式碼時提早捕捉潛在錯誤。例如:
const message = "hello!";
message(); // Error: This expression is not callable. Type 'String' has no call signatures.
TypeScript 靜態型別系統能在執行前提示 message
不是可呼叫的函式,而是字串。這種檢查可以降低執行時錯誤的機率。
對於諸如string或number這樣的原始類型,我們可以透過typeof操作符在運行時計算出它們的類型。 但像函數這樣的類型,並沒有對應的運行時機制去計算類型。例如:
function fn(x) {
return x.flip();
}
只有當存在一個帶有flip屬性的物件時,這個函數才可以正常運行,而JavaScript只提供了動態類型—— 實際呼叫fn函數,才能知道會發生什麼事。這使得我們很難在程式碼執行前進行相關的預測,在寫程式碼的時候,很難搞清楚程式碼會做什麼事。 所謂的型別就是描述了什麼值可以安全傳遞給fn,什麼值會造成報錯。
TypeScript 則是使用靜態的類型系統,在程式碼實際執行前預測程式碼的行為,在我們執行程式碼之前先拋出一個錯誤
JavaScript 的動態型別特性,使得試圖呼叫無法呼叫的東西、訪問物件上不存在的屬性時,可能不會直接報錯,它回傳的是值undefined。例如:
const user = {
name: 'Daniel',
age: 26,
};
user.location; // 返回 undefined
TypeScript 則會更嚴格地捕捉這類型錯誤:
const user = {
name: "Daniel",
age: 26,
};
user.location;
Property 'location' does not exist on type '{ name: string; age: number; }'.
再舉例: 拼字錯誤:
const announcement = "Hello World!";
// 你需要花多久才能注意到拼写错误?
announcement.toLocaleLowercase();
announcement.toLocalLowerCase();
// 实际上正确的拼写是这样的……
announcement.toLocaleLowerCase();
再舉例: 未呼叫的函數:
function flipCoin() {
// 应该是 Math.random()
return Math.random < 0.5;
Operator '<' cannot be applied to types '() => number' and 'number'.
}
再舉例: 基本的邏輯錯誤:
const value = Math.random() < 0.5 ? "a" : "b";
if (value !== "a") {
// ...
} else if (value === "b") {
This comparison appears to be unintentional because the types '"a"' and '"b"' have no overlap.
// 永远无法到达这个分支
}
TypeScript 的型別系統不僅幫助靜態檢查,還能提升開發效率。例如,現代編輯器會透過 TypeScript 提供即時的提示與補全功能:
import express from "express";
const app = express();
app.get("/", (req, res) => {
res.send // 提示所有可能的方法,如 send、sendFile 等。
});
tsc
TypeScript 的核心工具是 tsc
編譯器,它能將 .ts
檔案轉換為標準的 JavaScript 檔案。例如:
// hello.ts
console.log("Hello, TypeScript!");
執行以下命令:
tsc hello.ts
生成的 hello.js
檔案如下:
console.log("Hello, TypeScript!");
即使原始程式碼出現型別錯誤,tsc
預設仍會產出對應的 JavaScript 檔案。
預設情況下,即使 TypeScript 偵測到型別錯誤,tsc
仍會輸出編譯結果。但我們可以透過 --noEmitOnError
參數來避免這種情況:
tsc --noEmitOnError hello.ts
當啟用此設定後,若編譯過程中有錯誤,則不會輸出對應的 JavaScript 檔案。
雖然 TypeScript 具有型別推斷功能,但我們仍然可以明確指定變數的類型。例如:
function greet(person: string, date: Date) {
console.log(\`Hello ${person}, today is ${date.toDateString()}!\`);
}
greet("Maddison", new Date());
TypeScript 只在編譯期間檢查型別,而在生成的 JavaScript 中會移除這些型別註解。例如:
TypeScript 程式碼:
function greet(person: string, date: Date) {
console.log(\`Hello ${person}, today is ${date.toDateString()}!\`);
}
編譯後的 JavaScript:
function greet(person, date) {
console.log("Hello " + person + ", today is " + date.toDateString() + "!");
}
TypeScript 會將較新的 ECMAScript 語法轉換為目標 ECMAScript 版本。例如,模板字串會被降級為字串拼接:
console.log(\`Hello ${person}\`);
降級為:
console.log("Hello " + person);
我們可以透過 --target
選項指定目標版本,例如:
tsc --target es2015 hello.ts
TypeScript 提供多種嚴格性設定,例如:
noImplicitAny
若未顯式指定型別,TypeScript 預設會將變數型別視為 any
。啟用此選項後,任何隱含為 any
的變數都會導致錯誤。
strictNullChecks
預設情況下,null
和 undefined
可以賦值給任何變數。啟用此選項後,TypeScript 會強制開發者處理 null
和 undefined
的情況,減少因疏忽導致的錯誤。
File Title:
文章位置:
*
KM Steps:
MerMer 連結:
*