7 ویژگی پیشرفته TypeScript برای افزایش هزینه توسعه شما

به عنوان یک نویسنده پرفروش، از شما دعوت می کنم کتاب های من را در آمازون جستجو کنید. فراموش نکنید که من را در Medium دنبال کنید و حمایت خود را نشان دهید. متشکرم حمایت شما یعنی دنیا!
تایپ اسکریپت شیوه نوشتن برنامه های جاوا اسکریپت را متحول کرده است. به عنوان یک توسعه دهنده که به طور گسترده با TypeScript کار کرده است، از قدرت آن در ایجاد برنامه های کاربردی قوی، قابل نگهداری و مقیاس پذیر قدردانی کرده ام. در این مقاله، من تجربیات و بینش خود را در مورد هفت ویژگی پیشرفته TypeScript که می تواند روند توسعه شما را به طور قابل توجهی بهبود بخشد، به اشتراک بگذارم.
Type Guards یک ابزار قدرتمند در TypeScript است که به ما امکان می دهد انواع را در بلوک های شرطی محدود کنیم. آنها به ویژه هنگام کار با انواع اتحادیه یا زمانی که نیاز به انجام عملیات نوع خاص داریم مفید هستند. من محافظهای نوع را در بهبود ایمنی نوع و خوانایی کد بسیار ارزشمند یافتهام.
بیایید به یک مثال عملی نگاه کنیم:
function processValue(value: string | number) {
if (typeof value === "string") {
// TypeScript knows that 'value' is a string here
console.log(value.toUpperCase());
} else {
// TypeScript knows that 'value' is a number here
console.log(value.toFixed(2));
}
}
در این کد، typeof
چک به عنوان محافظ نوع عمل می کند و به TypeScript اجازه می دهد تا نوع صحیح را در هر بلوک استنباط کند. این از خطاها جلوگیری می کند و ما را قادر می سازد تا با اطمینان از روش های نوع خاص استفاده کنیم.
ما همچنین می توانیم محافظ های نوع سفارشی را برای سناریوهای پیچیده تر ایجاد کنیم:
interface Dog {
bark(): void;
}
interface Cat {
meow(): void;
}
function isDog(animal: Dog | Cat): animal is Dog {
return (animal as Dog).bark !== undefined;
}
function makeSound(animal: Dog | Cat) {
if (isDog(animal)) {
animal.bark(); // TypeScript knows this is safe
} else {
animal.meow(); // TypeScript knows this is safe
}
}
Mapped Types یکی دیگر از ویژگی هایی است که به نظر من بسیار مفید است. آنها به ما اجازه می دهند تا انواع جدیدی را بر اساس انواع موجود ایجاد کنیم، که می تواند به طور قابل توجهی تکرار کد را کاهش دهد و تعاریف نوع ما را پویاتر کند.
در اینجا مثالی از نحوه استفاده من از انواع نگاشت برای ایجاد یک نسخه فقط خواندنی از یک رابط آورده شده است:
interface User {
id: number;
name: string;
email: string;
}
type ReadonlyUser = {
readonly [K in keyof User]: User[K];
};
const user: ReadonlyUser = {
id: 1,
name: "John Doe",
email: "john@example.com",
};
// This would cause a TypeScript error
// user.name = "Jane Doe";
Conditional Types در پروژه های TypeScript من یک تغییر دهنده بازی بوده است. آنها به ما اجازه میدهند تا تعاریف نوع را ایجاد کنیم که به انواع دیگر بستگی دارد و سیستمهای نوع انعطافپذیرتر و گویاتر را امکانپذیر میسازد.
من اغلب هنگام کار با توابع عمومی از انواع شرطی استفاده می کنم:
type NonNullable<T> = T extends null | undefined ? never : T;
function processValue<T>(value: T): NonNullable<T> {
if (value === null || value === undefined) {
throw new Error("Value cannot be null or undefined");
}
return value as NonNullable<T>;
}
const result = processValue("Hello"); // Type is string
const nullResult = processValue(null); // TypeScript error
Literal Types یکی دیگر از ویژگی هایی است که به نظر من بسیار مفید است. آنها به ما اجازه می دهند تا انواعی را تعریف کنیم که مقادیر دقیق را نشان می دهند، که می تواند برای جلوگیری از خطاها و بهبود بررسی نوع بسیار مفید باشد.
در اینجا مثالی از نحوه استفاده از انواع تحت اللفظی در کد خود آورده شده است:
type Direction = "north" | "south" | "east" | "west";
function move(direction: Direction) {
// Implementation
}
move("north"); // This is valid
// move("up"); // This would cause a TypeScript error
اتحادیه های تبعیض شده به بخشی ضروری از جعبه ابزار TypeScript من تبدیل شده اند. آنها انواع اتحادیه را با یک ویژگی متمایز مشترک ترکیب می کنند، که امکان تعاریف دقیق تر نوع و مدیریت آسان تر ساختارهای داده پیچیده را فراهم می کند.
در اینجا نمونه ای از نحوه استفاده از اتحادیه های تبعیض آمیز آمده است:
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
type Shape = Square | Rectangle;
function calculateArea(shape: Shape) {
switch (shape.kind) {
case "square":
return shape.size * shape.size;
case "rectangle":
return shape.width * shape.height;
}
}
Generics یک ویژگی قدرتمند است که من اغلب از آن برای ایجاد اجزا و عملکردهای قابل استفاده مجدد استفاده می کنم. آنها به ما اجازه می دهند تا کدی بنویسیم که بتواند با چندین نوع کار کند و در عین حال ایمنی نوع را حفظ کند.
در اینجا یک مثال از یک تابع عمومی است که من ممکن است استفاده کنم:
function reverseArray<T>(array: T[]): T[] {
return array.reverse();
}
const numbers = reverseArray([1, 2, 3, 4, 5]);
const strings = reverseArray(["a", "b", "c", "d"]);
دکوراتورها ویژگیای هستند که به ویژه هنگام کار با کلاسها مفید بودهاند. آنها به ما اجازه می دهند که متادیتا اضافه کنیم یا رفتار کلاس ها، متدها و خصوصیات را در زمان اجرا تغییر دهیم.
در اینجا یک نمونه از یک دکوراتور ساده است که ممکن است استفاده کنم:
function log(target: any, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${key} with arguments: ${JSON.stringify(args)}`);
return originalMethod.apply(this, args);
};
return descriptor;
}
class Calculator {
@log
add(a: number, b: number) {
return a + b;
}
}
const calc = new Calculator();
calc.add(5, 3); // Logs: Calling add with arguments: [5,3]
این ویژگی های پیشرفته TypeScript به طور قابل توجهی روند توسعه من را بهبود بخشیده است. آنها به من اجازه داده اند کد قوی تر و ایمن تر بنویسم، خطاها را زودتر در چرخه توسعه پیدا کنم و برنامه های قابل نگهداری بیشتری ایجاد کنم.
Type Guards به ویژه در سناریوهایی که من با داده های API های خارجی کار می کنم مفید بوده اند. آنها به من اجازه می دهند تا با خیال راحت انواع را محدود کنم و موارد مختلف را بدون خطر خطاهای زمان اجرا مدیریت کنم.
Mapped Types ساعت های بی شماری را از نوشتن تعاریف تکراری تایپ نجات داده است. من از آنها برای ایجاد انواع ابزاری استفاده کردهام که رابطهای موجود را به روشهای مختلف تغییر میدهند، مانند اختیاری کردن همه ویژگیها یا فقط خواندنی کردن.
انواع شرطی هنگام کار با توابع عمومی پیچیده بسیار ارزشمند بوده اند. آنها به من اجازه دادند تا تعاریف نوع انعطافپذیرتری را ایجاد کنم که بر اساس انواع ورودی تطبیق مییابد و به سیستمهای نوع گویاتر و دقیقتر منجر میشود.
Literal Types یک تغییر دهنده بازی برای جلوگیری از اشکالات مربوط به رشته یا مقادیر اعداد نادرست بوده است. من از آنها به طور گسترده برای تعریف گزینه های معتبر برای اشیاء پیکربندی استفاده کرده ام و اطمینان حاصل کنم که فقط از مقادیر مجاز استفاده می شود.
اتحادیه های تبعیض شده به ویژه هنگام کار با مدیریت دولتی در برنامه های React مفید بوده اند. آنها به من اجازه دادند تا انواع دقیقی را برای حالت های مختلف تعریف کنم، و مدیریت منطق پیچیده UI و جلوگیری از حالت های غیرممکن را آسان تر می کند.
ژنریک ها هسته اصلی بسیاری از توابع و اجزای کاربردی قابل استفاده مجدد من بوده اند. آنها به من اجازه دادهاند تا کد قابل انعطاف و ایمن بنویسم که میتواند با انواع دادهها بدون به خطر انداختن بررسی نوع کار کند.
دکوراتورها برای جنبه هایی مانند ورود به سیستم، اعتبارسنجی و ذخیره سازی بسیار مفید بوده اند. من از آنها برای اضافه کردن نگرانی های مقطعی به کلاس های خود بدون درهم ریختن منطق اصلی استفاده کرده ام که منجر به کدهای تمیزتر و قابل نگهداری تر می شود.
در تجربه من، این ویژگی های پیشرفته TypeScript هنگام استفاده ترکیبی واقعا می درخشند. به عنوان مثال، من ممکن است از ژنریک ها با انواع شرطی برای ایجاد انواع ابزار انعطاف پذیر استفاده کنم، یا اتحادیه های تبعیض آمیز را با محافظ های نوع برای مدیریت دولتی قوی ترکیب کنم.
یکی از الگوهایی که من به ویژه قدرتمند یافتم استفاده از انواع نقشهبرداری شده با انواع شرطی برای ایجاد انواع ابزار پیشرفته است. در اینجا یک مثال است:
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
interface User {
id: number;
name: string;
settings: {
theme: string;
notifications: boolean;
};
}
type ReadonlyUser = DeepReadonly<User>;
const user: ReadonlyUser = {
id: 1,
name: "John",
settings: {
theme: "dark",
notifications: true,
},
};
// These would all cause TypeScript errors:
// user.id = 2;
// user.settings.theme = "light";
// user.settings = { theme: "light", notifications: false };
این DeepReadonly
type به صورت بازگشتی همه خصوصیات یک شی (و اشیاء تودرتو) را فقط خواندنی می کند. این یک مثال عالی از قدرت سیستم نوع TypeScript در هنگام استفاده از این ویژگی های پیشرفته است.
الگوی دیگری که من مفید یافتم، ترکیب ژنریک ها با اتحادیه های تبعیض آمیز برای ایجاد سیستم های رویداد ایمن از نوع است:
type EventMap = {
login: { user: string; timestamp: number };
logout: { user: string; timestamp: number };
purchase: { item: string; price: number; timestamp: number };
};
class EventEmitter<T extends EventMap> {
private listeners: { [K in keyof T]?: ((event: T[K]) => void)[] } = {};
on<K extends keyof T>(event: K, listener: (event: T[K]) => void) {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event]!.push(listener);
}
emit<K extends keyof T>(event: K, data: T[K]) {
if (this.listeners[event]) {
this.listeners[event]!.forEach((listener) => listener(data));
}
}
}
const emitter = new EventEmitter<EventMap>();
emitter.on("login", ({ user, timestamp }) => {
console.log(`${user} logged in at ${new Date(timestamp)}`);
});
emitter.emit("login", { user: "John", timestamp: Date.now() });
// This would cause a TypeScript error:
// emitter.emit("login", { user: "John" });
این الگو تضمین می کند که رویدادها با نوع بار صحیح منتشر می شوند، از خطاهای زمان اجرا جلوگیری می کند و قابلیت اطمینان کد را بهبود می بخشد.
در نتیجه، این ویژگی های پیشرفته TypeScript به ابزارهای ضروری در جعبه ابزار توسعه من تبدیل شده اند. آنها به من اجازه داده اند تا برنامه های جاوا اسکریپت قوی تر، قابل نگهداری و مقیاس پذیرتر بنویسم. با استفاده از محافظهای نوع، انواع نقشهبرداری شده، انواع شرطی، انواع تحت اللفظی، اتحادیههای تبعیضآمیز، ژنریکها، و دکوراتورها، توانستم تعاریف نوع دقیقتری ایجاد کنم، خطاها را زودتر در فرآیند توسعه تشخیص دهم و کد گویاتری بنویسم.
با این حال، توجه به این نکته مهم است که با قدرت زیاد، مسئولیت بزرگی نیز به همراه دارد. در حالی که این ویژگی ها می توانند کد ما را به طور قابل توجهی بهبود بخشند، اما اگر به طور عاقلانه استفاده نشوند، می توانند به تعاریف نوع بسیار پیچیده منجر شوند. مانند هر ابزار دیگری، نکته کلیدی استفاده از آنها در جایی است که مزایای واضحی را ارائه می دهند و کیفیت کد را بهبود می بخشند.
من همه توسعه دهندگان جاوا اسکریپت را تشویق می کنم که این ویژگی های پیشرفته TypeScript را بررسی کنند. آنها ممکن است در ابتدا دلهره آور به نظر برسند، اما با تمرین، به متحدان قدرتمندی در ایجاد برنامه های کاربردی با کیفیت بالا و ایمن تبدیل می شوند. زمان صرف شده برای یادگیری و به کارگیری این ویژگیها به شکل باگهای کمتر، خوانایی کد بهبود یافته و پایگاههای کد قابل نگهداری بیشتر نتیجه خواهد داد.
به یاد داشته باشید، TypeScript فقط در مورد افزودن انواع به جاوا اسکریپت نیست. این در مورد استفاده از سیستم نوع برای نوشتن کد بهتر و ایمن تر است. این ویژگی های پیشرفته فقط قند نحوی نیستند – آنها ابزارهای قدرتمندی هستند که می توانند به طور اساسی نحوه طراحی و اجرای برنامه های خود را بهبود بخشند.
همانطور که اکوسیستم جاوا اسکریپت به تکامل خود ادامه می دهد، من هیجان زده هستم که ببینم TypeScript و ویژگی های پیشرفته آن چگونه آینده توسعه وب را شکل خواهد داد. با تسلط بر این ابزارها، ما خود را در خط مقدم این تکامل قرار می دهیم و آماده ساختن برنامه های کاربردی قوی و مقیاس پذیر فردا هستیم.
101 کتاب
101 کتاب یک شرکت انتشاراتی مبتنی بر هوش مصنوعی است که با همکاری نویسنده تأسیس شده است آراو جوشی. با استفاده از فناوری پیشرفته هوش مصنوعی، هزینههای انتشار خود را بهطور باورنکردنی پایین نگه میداریم—بعضی کتابها قیمت پایینی دارند. 4 دلار– در دسترس قرار دادن دانش با کیفیت برای همه.
کتاب ما را بررسی کنید کد پاک گلانگ در آمازون موجود است.
منتظر به روز رسانی ها و اخبار هیجان انگیز باشید. هنگام خرید کتاب، جستجو کنید آراو جوشی برای یافتن عناوین بیشتر ما برای لذت بردن از لینک ارائه شده استفاده کنید تخفیف های ویژه!
مخلوقات ما
حتماً خلاقیت های ما را بررسی کنید:
مرکز سرمایه گذار | سرمایه گذار اسپانیایی مرکزی | سرمایه گذار آلمان مرکزی | زندگی هوشمند | دوره ها و پژواک ها | اسرار گیج کننده | هندوتوا | Elite Dev | مدارس JS
ما در حالت متوسط هستیم
بینش کوآلای فنی | دوران و پژواک جهان | سرمایه گذار مرکزی متوسط | رازهای گیج کننده رسانه | رسانه علم و عصر | هندوتوای مدرن