[Easy] 基本型別與型別註解
1. What are TypeScript Basic Types?
TypeScript 的基本型別有哪些?
TypeScript 提供了多種基本型別,用於定義變數、函式參數 和回傳值的型別。
基本型別
// 1. number:數字(整數、浮點數)
let age: number = 30;
let price: number = 99.99;
// 2. string:字串
let name: string = 'John';
let message: string = `Hello, ${name}!`;
// 3. boolean:布林值
let isActive: boolean = true;
let isCompleted: boolean = false;
// 4. null: 空值
let data: null = null;
// 5. undefined:未定義
let value: undefined = undefined;
// 6. void:無回傳值(主要用於函式)
function logMessage(): void {
console.log('Hello');
}
// 7. any:任意型別(應避免使用)
let anything: any = 'hello';
anything = 42;
anything = true;
// 8. unknown:未知型別(比 any 更安全)
let userInput: unknown = 'hello';
// userInput.toUpperCase(); // ❌ 錯誤:需要先檢查型別
// 9. never:永遠不會發生的值(用於永遠不會回傳的函式)
function throwError(): never {
throw new Error('Error');
}
// 10. object:物件(不常用,建議使用介面)
let user: object = { name: 'John' };
// 11. array:陣列
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ['John', 'Jane'];
// 12. tuple:元組(固定長度和型別的陣列)
let person: [string, number] = ['John', 30];
2. Type Annotations vs Type Inference
型別註解 vs 型別推斷
型別註解(Type Annotations)
定義:明確指定變數的型別。
// 明確指定型別
let age: number = 30;
let name: string = 'John';
let isActive: boolean = true;
// 函式參數和回傳值
function add(a: number, b: number): number {
return a + b;
}
型別推斷(Type Inference)
定義:TypeScript 根據初始值自動推斷型別。
// TypeScript 自動推斷為 number
let age = 30; // age: number
// TypeScript 自動推斷為 string
let name = 'John'; // name: string
// TypeScript 自動推斷為 boolean
let isActive = true; // isActive: boolean
// 函式回傳值也會自動推斷
function add(a: number, b: number) {
return a + b; // 自動推斷回傳值為 number
}
何時使用型別註解
需要明確指定型別的情況:
// 1. 變數宣告時沒有初始值
let value: number;
value = 10;
// 2. 函式參數(必須指定)
function greet(name: string): void {
console.log(`Hello, ${name}!`);
}
// 3. 函式回傳值(建議明確指定)
function calculate(): number {
return 42;
}
// 4. 複雜型別,推斷可能不準確
let data: { name: string; age: number } = {
name: 'John',
age: 30,
};
3. Common Interview Questions
常見面試題目
題目 1:型別推斷
請說明以下程式碼中每個變數的型別。
let value1 = 10;
let value2 = 'hello';
let value3 = true;
let value4 = [1, 2, 3];
let value5 = { name: 'John', age: 30 };
點擊查看答案
let value1 = 10; // number
let value2 = 'hello'; // string
let value3 = true; // boolean
let value4 = [1, 2, 3]; // number[]
let value5 = { name: 'John', age: 30 }; // { name: string; age: number }
解釋:
- TypeScript 會根據初始值自動推斷型別
- 陣列推斷為元素型別的陣列
- 物件推斷為物件的結構型別
題目 2:型別錯誤
請找出以下程式碼中的型別錯誤。
let age: number = 30;
age = 'thirty';
let name: string = 'John';
name = 42;
let isActive: boolean = true;
isActive = 'yes';
let numbers: number[] = [1, 2, 3];
numbers.push('4');
點擊查看答案
let age: number = 30;
age = 'thirty'; // ❌ Type 'string' is not assignable to type 'number'
let name: string = 'John';
name = 42; // ❌ Type 'number' is not assignable to type 'string'
let isActive: boolean = true;
isActive = 'yes'; // ❌ Type 'string' is not assignable to type 'boolean'
let numbers: number[] = [1, 2, 3];
numbers.push('4'); // ❌ Argument of type 'string' is not assignable to parameter of type 'number'
正確寫法:
let age: number = 30;
age = 30; // ✅
let name: string = 'John';
name = 'Jane'; // ✅
let isActive: boolean = true;
isActive = false; // ✅
let numbers: number[] = [1, 2, 3];
numbers.push(4); // ✅
題目 3:any vs unknown
請說明 any 和 unknown 的差異,並說明應該使用哪一個。
// 情況 1:使用 any
function processAny(value: any): void {
console.log(value.toUpperCase()); // ?
}
// 情況 2:使用 unknown
function processUnknown(value: unknown): void {
console.log(value.toUpperCase()); // ?
}
點擊查看答案
情況 1:使用 any
function processAny(value: any): void {
console.log(value.toUpperCase()); // ⚠️ 編譯通過,但執行時可能出錯
}
processAny('hello'); // ✅ 正常執行
processAny(42); // ❌ 執行時錯誤:value.toUpperCase is not a function
情況 2:使用 unknown
function processUnknown(value: unknown): void {
// console.log(value.toUpperCase()); // ❌ 編譯錯誤:Object is of type 'unknown'
// 需要先檢查型別
if (typeof value === 'string') {
console.log(value.toUpperCase()); // ✅ 安全
}
}
差異比較:
| 特性 | any | unknown |
|---|---|---|
| 型別檢查 | 完全關閉 | 需要先檢查才能使用 |
| 安全性 | 不安全 | 安全 |
| 使用建議 | 避免使用 | 推薦使用 |
最佳實踐:
// ✅ 推薦:使用 unknown,然後進行型別檢查
function processValue(value: unknown): void {
if (typeof value === 'string') {
console.log(value.toUpperCase());
} else if (typeof value === 'number') {
console.log(value.toFixed(2));
}
}
// ❌ 避免:使用 any
function processValue(value: any): void {
console.log(value.toUpperCase()); // 不安全
}