15 نکته پیشرفته TypeScript برای توسعه
1. زنجیربندی اختیاری (?.):
زنجیرهسازی اختیاری به شما امکان میدهد بدون نگرانی در مورد مقادیر تهی یا تعریفنشده، با خیال راحت به ویژگیها یا روشهای تودرتو دسترسی داشته باشید. در صورت تهی بودن یا تعریف نشدن خاصیت میانی، ارزیابی را کوتاه می کند.
const user = {
name: 'John',
address: {
city: 'New York',
postalCode: '12345'
}
};
const postalCode = user.address?.postalCode;
console.log(postalCode); // Output: 12345
const invalidCode = user.address?.postalCode?.toLowerCase();
console.log(invalidCode); // Output: undefined
2. اپراتور ادغام باطل (??):
عملگر ادغام تهی یک مقدار پیش فرض را زمانی که یک متغیر تهی یا تعریف نشده باشد ارائه می دهد.
const name = null;
const defaultName = name ?? 'Unknown';
console.log(defaultName); // Output: Unknown
const age = 0;
const defaultAge = age ?? 18;
console.log(defaultAge); // Output: 0
3. نوع ادعا:
Type assertion به شما امکان می دهد تا زمانی که TypeScript قادر به استنباط آن نیست، نوع متغیر را به صراحت تعریف کنید.
const userInput: unknown = 'Hello World';
const strLength = (userInput as string).length;
console.log(strLength); // Output: 11
4. ژنریک:
Generics شما را قادر می سازد تا اجزای قابل استفاده مجدد ایجاد کنید که می توانند با انواع مختلف کار کنند.
function reverse<T>(items: T[]): T[] {
return items.reverse();
}
const numbers = [1, 2, 3, 4, 5];
const reversedNumbers = reverse(numbers);
console.log(reversedNumbers); // Output: [5, 4, 3, 2, 1]
const strings = ['a', 'b', 'c'];
const reversedStrings = reverse(strings);
console.log(reversedStrings); // Output: ['c', 'b', 'a']
5. کلید اپراتور:
عملگر keyof اتحادی از همه نامهای مشخصه مشخصه از یک نوع مشخص را برمیگرداند.
interface User {
id: number;
name: string;
email: string;
}
function getUserProperty(user: User, property: keyof User) {
return user[property];
}
const user: User = {
id: 1,
name: 'John Doe',
email: 'john@example.com'
};
const name = getUserProperty(user, 'name');
console.log(name); // Output: John Doe
const invalidProperty = getUserProperty(user, 'age'); // Error: Argument of type '"age"' is not assignable to parameter of type '"id" | "name" | "email"'
6. نوع محافظ:
محافظهای نوع به شما امکان میدهند تا بر اساس یک شرایط خاص، نوع متغیر را در یک بلوک شرطی محدود کنید.
function logMessage(message: string | number) {
if (typeof message === 'string') {
console.log('Message: ' + message.toUpperCase());
} else {
console.log('Value: ' + message.toFixed(2));
}
}
logMessage('hello'); // Output: Message: HELLO
logMessage(3.14159); // Output: Value: 3.14
7-انواع تقاطع:
انواع تقاطع به شما این امکان را می دهد که چندین نوع را در یک نوع واحد ترکیب کنید و نوع جدیدی را ایجاد کنید که تمام ویژگی ها و روش های انواع متقاطع را دارد.
interface Loggable {
log: () => void;
}
interface Serializable {
serialize: () => string;
}
type Logger = Loggable & Serializable;
class ConsoleLogger implements Loggable {
log() {
console.log('Logging to console...');
}
}
class FileLogger implements Loggable, Serializable {
log() {
console.log('Logging to file...');
}
serialize() {
return 'Serialized log data';
}
}
const logger1: Logger = new ConsoleLogger();
logger1.log(); // Output: Logging to console...
const logger2: Logger = new FileLogger();
logger2.log(); // Output: Logging to file...
console.log(logger2.serialize()); // Output: Serialized log data
8. انواع نقشه برداری:
انواع نگاشت شده به شما اجازه می دهد تا با تبدیل ویژگی های یک نوع موجود، انواع جدیدی ایجاد کنید.
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = { [K in keyof User]?: User[K] };
const partialUser: PartialUser = {
name: 'John Doe',
email: 'john@example.com'
};
console.log(partialUser); // Output: { name: 'John Doe', email: 'john@example.com' }
9. انواع لفظی رشته و انواع اتحادیه:
TypeScript از انواع رشتهای و انواع اتحادیه پشتیبانی میکند که میتوانند برای تعریف مجموعههای خاصی از مقادیر برای یک متغیر استفاده شوند.
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
function sendRequest(url: string, method: HttpMethod) {
// send request logic here...
}
sendRequest('/users', 'GET');
sendRequest('/users', 'POST');
sendRequest('/users/1', 'PUT');
sendRequest('/users/1', 'DELETE');
10. دکوراتورها:
دکوراتورها به شما این امکان را میدهند که رفتار کلاسها، روشها، ویژگیها و سایر اعلانها را اصلاح یا گسترش دهید.
function uppercase(target: any, propertyKey: string) {
let value = target[propertyKey];
const getter = () => value;
const setter = (newValue: string) => {
value = newValue.toUpperCase();
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
class Person {
@uppercase
name: string;
}
const person = new Person();
person.name = 'John Doe';
console.log(person.name); // Output: JOHN DOE
11. امضاهای فهرست:
امضاهای شاخص به شما امکان می دهند نام ویژگی های پویا و انواع مربوط به آنها را در یک رابط یا نوع تعریف کنید.
interface Dictionary {
[key: string]: number;
}
const scores: Dictionary = {
math: 90,
science: 85,
history: 95
};
console.log(scores['math']); // Output: 90
console.log(scores['english']); // Output: undefined
12. نوع استنتاج با عبارات شرطی:
TypeScript می تواند انواع را بر اساس عبارات شرطی استنباط کند، که امکان کد مختصرتر را فراهم می کند.
function calculateTax(amount: number, isTaxable: boolean) {
if (isTaxable) {
return amount * 1.1; // Type: number
} else {
return amount; // Type: number
}
}
const taxableAmount = calculateTax(100, true);
console.log(taxableAmount.toFixed(2)); // Output: 110.00
const nonTaxableAmount = calculateTax(100, false);
console.log(nonTaxableAmount.toFixed(2)); // Output: 100.00
13. Readonly Properties:
TypeScript اصلاح کننده فقط خواندنی را برای تعریف ویژگی هایی که پس از مقداردهی اولیه قابل تغییر نیستند ارائه می دهد.
class Circle {
readonly radius: number;
constructor(radius: number) {
this.radius = radius;
}
getArea() {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.radius); // Output: 5
// circle.radius = 10; // Error: Cannot assign to 'radius' because it is a read-only property
console.log(circle.getArea()); // Output: 78.53981633974483
14. نام مستعار را تایپ کنید:
نام مستعار نوع به شما امکان می دهد نام های سفارشی را برای انواع موجود ایجاد کنید، که معنای معنایی بیشتری ارائه می دهد و خوانایی کد را بهبود می بخشد.
type Point = {
x: number;
y: number;
};
type Shape = 'circle' | 'square' | 'triangle';
function draw(shape: Shape, position: Point) {
console.log(`Drawing a ${shape} at (${position.x}, ${position.y})`);
}
const startPoint: Point = { x: 10, y: 20 };
draw('circle', startPoint); // Output: Drawing a circle at (10, 20)
15. نوع نگهبان با کلاس ها:
محافظ های نوع همچنین می توانند با کلاس ها برای محدود کردن نوع نمونه شی استفاده شوند.
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
}
class Dog extends Animal {
bark() {
console.log('Woof!');
}
}
function makeSound(animal: Animal) {
if (animal instanceof Dog) {
animal.bark(); // Type: Dog
} else {
console.log('Unknown animal');
}
}
const dog = new Dog('Buddy');
const animal = new Animal('Unknown');
makeSound(dog); // Output: Woof!
makeSound(animal); // Output: Unknown animal