فصل ۳: شروع کدنویسی با TypeScript - تایپ بزن، خیالت راحت!
اهمیت سیستم تایپ در TypeScript
چرا تایپها مهم هستند؟
سیستم تایپ TypeScript مزایای متعددی برای توسعهدهندگان فراهم میکند:
-
کشف زودهنگام خطاها:
- شناسایی مشکلات قبل از اجرای کد
- کاهش خطاهای زمان اجرا (Runtime Errors)
-
خودمستندسازی کد:
- تایپها به عنوان مستندات زنده عمل میکنند
- بهبود خوانایی و درک کد
-
پشتیبانی بهتر ابزارها:
- تکمیل خودکار کد (Autocompletion)
- بازسازی ایمن کد (Safe Refactoring)
-
مدیریت پروژههای بزرگ:
- نگهداری آسانتر کد
- همکاری بهتر بین توسعهدهندگان
تفاوت تایپ استاتیک و داینامیک
| ویژگی | TypeScript (استاتیک) | JavaScript (داینامیک) |
|---|---|---|
| بررسی تایپ | زمان کامپایل | زمان اجرا |
| انعطافپذیری | کمتر | بیشتر |
| امنیت نوع | بالا | پایین |
| کارایی در تیم | عالی | چالشبرانگیز |
انواع داده اولیه در TypeScript
اعداد (Number)
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
رشتهها (String)
let fullName: string = "آرش کاظمی";
let sentence: string = `سلام، نام من ${fullName} است.`;
مقادیر منطقی (Boolean)
let isDone: boolean = false;
let isActive: boolean = true;
آرایهها
// روش اول
let list1: number[] = [1, 2, 3];
// روش دوم (Generic)
let list2: Array<number> = [1, 2, 3];
تاپل (Tuple)
let person: [string, number] = ["آرش", 25];
// ترتیب عناصر مهم است
Enum
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
Any
let dynamicValue: any = 4;
dynamicValue = "متن";
dynamicValue = false;
Void
function logMessage(): void {
console.log("این تابع مقداری برنمیگرداند");
}
Null و Undefined
let u: undefined = undefined;
let n: null = null;
Never
function error(message: string): never {
throw new Error(message);
}
Object
let user: object = {name: "آرش", age: 30};
استنتاج تایپ و حاشیهنویسی در TypeScript
استنتاج تایپ (Type Inference)
TypeScript در بسیاری موارد میتواند تایپ را خودش تشخیص دهد:
let x = 3; // TypeScript میفهمد x از نوع number است
let y = "سلام"; // y به عنوان string شناخته میشود
حاشیهنویسی تایپ (Type Annotations)
وقتی میخواهیم تایپ را صریحاً مشخص کنیم:
let name: string = "آرش";
let age: number = 30;
let isActive: boolean = true;
موارد نیاز به حاشیهنویسی
- 1.وقتی متغیر بدون مقدار اولیه تعریف میشود:
let username: string;
username = "user123";
- 2.پارامترهای تابع:
function greet(name: string) {
return `سلام ${name}`;
}
- 3.مقدار بازگشتی تابع:
function add(a: number, b: number): number {
return a + b;
}
بهترین روشها
- از استنتاج تایپ وقتی که مقدار اولیه واضح است استفاده کنید
- برای پارامترهای تابع و مقادیر بازگشتی همیشه تایپ را مشخص کنید
- از
anyاستفاده نکنید مگر در موارد خاص
مقایسه Type و Interface در TypeScript
تعریف Type Aliases
type Point = {
x: number;
y: number;
};
type ID = string | number;
جدول مقایسه ویژگیهای کلیدی
| ویژگی | Type Aliases | Interfaces |
|---|---|---|
| ادغام (Declaration Merging) | ❌ پشتیبانی نمیشود | ✔️ به صورت خودکار ادغام میشوند |
| ارثبری (Extending) | با استفاده از عملگر & (Intersection) | با استفاده از کلمه کلیدی extends |
| پیادهسازی در کلاسها | ❌ نمیتوان با implements استفاده کرد | ✔️ قابل پیادهسازی در کلاسها |
| تعریف توابع | ✔️ پشتیبانی میکندtype Greet = (name: string) => string; | ✔️ پشتیبانی میکند interface Greet { (name: string): string; } |
| تایپهای پیچیده | ✔️ عالی برای Union Types، Intersection و Conditional Types | ⚠️ بیشتر برای اشیاء و شکلدادن ساختار داده مناسب است |
| Literal Types | ✔️ پشتیبانی کامل | ❌ پشتیبانی نمیشود |
| Mapped Types | ✔️ پشتیبانی کامل | ❌ پشتیبانی نمیشود |
| خوانایی | ⚠️ برای تایپهای پیچیده ممکن است کمتر خوانا باشد | ✔️ ساختار تمیز و خوانایی بهتر |
مثالهای کاربردی
- ۱. ارثبری در Type
type Person = {
name: string;
};
type Employee = Person & {
id: number;
};
- ۲. ارثبری در Interface
interface Person {
name: string;
}
interface Employee extends Person {
id: number;
}
- ۳. Union Types (فقط در Type)
type ID = string | number;
با آرزوی موفقیت
تیم برندآرا 🤖