مطالب
مبانی TypeScript؛ کلاس‌ها
تا قبل از ES 6 در جاوا اسکریپت از توابع جهت ایجاد کامپوننت‌هایی با قابلیت استفاده مجدد استفاده می‌شد. این امر برای برنامه‌نویسانی که با زبان‌های OOP آشنایی دارند، شاید چندان خوشایند نباشد. در TypeScript نیز همانند ES 6 امکان استفاده از کلاس‌ها مهیا است.
در حالت کلی یک کلاس قالبی برای ایجاد اشیاء است. تمامی اشیاء ایجاد شده از این الگو دارای یکسری پراپرتی و متد می‌باشند. از پراپرتی‌ها جهت تعریف وضعیت‌ها و از متدها جهت تعریف رفتارها استفاده خواهد شد. همچنین مزیت اصلی یک کلاس، کپسوله‌سازی قابلیت‌های یک موجودیت خاص است. همانند دیگر زبان‌های شیءگرا، در TypeScript نیز یک کلاس می‌تواند ویژگی‌های زیر را داشته باشد:
  • سازنده (constructor)
  • پراپرتی، متد
  • Access Modifiers
  • ارث‌بری
  • کلاس‌های Abstract
در ادامه هر کدام از موارد فوق را بررسی خواهیم کرد.

سازنده (Constructor)
از سازنده‌ها جهت مقداردهی وهله‌های یک کلاس استفاده می‌شود. در ادامه یک کلاس جدید را با استفاده از کلمه‌ی کلیدی class ایجاد کرده‌ایم. این کلاس دارای یک سازنده است:
class ReferenceItem {
    constructor(title: string, publisher?: string) {
        // perform initialization here
    }
}
همانطور که مشاهده می‌کنید یک سازنده شبیه به یک متد است؛ با این تفاوت که برای نام آن از کلمه کلیدی constructor استفاده می‌شود. در TypeScript برای یک کلاس تنها یک سازنده را می‌توانیم داشته باشیم. البته در دیگر زبان‌های برنامه‌نویسی امکان تعریف چندین سازنده را با پارامترهای مختلف برای یک کلاس می‌توانید داشته باشید. برای رسیدن به این هدف در TypeScript می‌توان از Optional Parameters استفاده کرد. برای ایجاد یک وهله از کلاس فوق می‌توانیم به این صورت عمل کنیم:
let encyclopedia = new ReferenceItem('WorldPedia', 'WorldPub');
در کد فوق با استفاده از کلمه‌ی کلیدی new یک وهله از کلاس ReferenceItem را ایجاد کرده‌ایم و در نهایت آن را به متغیری با نام encyclopedia انتساب داده‌ایم. یعنی در واقع با استفاده از new توانسته‌ایم سازنده‌ی کلاس را فراخوانی کرده و سپس وهله‌ایی از آن را به متغیر ذکر شده انتساب دهیم.

پراپرتی، متد 
همانند اینترفیس‌ها، کلاس‌ها نیز می‌توانند پراپرتی و متد داشته باشند. با این تفاوت که در کلاس‌ها جزئیات پیاده‌سازی نیز ذکر خواهد شد. در یک کلاس به دو روش متفاوت می‌توانیم پراپرتی را تعریف کنیم. روش اول همانند تعریف یک متغیر است. به عنوان مثال در کلاس زیر یک پراپرتی با نام numberOfPages را از نوع عددی تعریف کرده‌ایم:
class ReferenceItem {
    numberOfPages: number;
}
برای دسترسی به این پراپرتی می‌توانیم از سینتکس نقطه (.) استفاده کنیم. روش دوم برای تعریف یک پراپرتی، ایجاد accessor‌های سفارشی است. accessors در واقع توابع getter و setter هستند که به شما در نحوه‌ی get و set کردن یک پراپرتی کمک خواهند کرد:
class ReferenceItem {
    numberOfPages: number;
    
    get editor(): string {
        // custom getter logic goes here, should return a value
    }
    
    set editor(newEditor: string) {
        // custom setter logic goes here
    }
}
همانطور که مشاهده می‌کنید، accessorهایی را برای پراپرتی editor با استفاده از کلمات کلیدی get و set ایجاد کرده‌ایم. این accessorها در واقع توابعی همنام هستند. تابع get همیشه فاقد پارامتر است. می‌توانیم برای تابع get نوع برگشتی را نیز تعیین کنیم (به عنوان مثال در کد فوق نوع برگشتی string است). setter نیز باید تنها یک پارامتر از ورودی دریافت کند. همچنین نمی‌توانیم برای آن نوع برگشتی را تعیین کنیم. درون بدنه‌ی این accessorها می‌توانیم هر نوع کنترلی را بر روی پراپرتی داشته باشیم. برای دسترسی این accessorها نیز باید از سینتکس نقطه (.) استفاده کنیم.
متدها نیز توابعی هستند که درون یک کلاس تعریف می‌شوند. برای نمونه در کد زیر یک تابع با نام printChapterTitle را تعریف کرده‌ایم که یک پارامتر را از ورودی دریافت کرده و هیچ مقداری را در خروجی بر نمی‌گرداند:
class ReferenceItem {
    numberOfPages: number;
    
    get editor(): string {
        // custom getter logic goes here, should return a value
    }
    
    set editor(newEditor: string) {
        // custom setter logic goes here
    }
    
    printChapterTitle(chapterNum: number): void {
        // print title here
    }
}

Parameter properties
در حالت عادی برای مقداردهی اولیه‌ی پراپرتی‌ها یک شیء می‌توانیم یکسری پارامتر را برای سازنده کلاس تعریف کرده و درون سازنده، پراپرتی‌های موردنیازمان را مقداردهی کنیم:
class Author {
    name: string;
    
    constructor(authorName: string) {
        name = authorName;
    }
}
با کمک Parameter properties می‌توانیم به صورت خلاصه‌تری اینکار را انجام دهیم:
class Author {
    constructor(public name: string){}
}
همانطور که مشاهده می‌کنید اینکار را با افزودن کلمه‌ی کلیدی public به ابتدای پارامتر name انجام داده‌ایم. در این‌حالت دیگر نیازی به تعریف یک پراپرتی اضافی درون کلاس نخواهیم داشت. کامپایلر TypeScript خودش یک پراپرتی را با همین نام ایجاد کرده و مقدار دریافتی از سازنده را برای آن ست خواهد کرد.

Static Properties
تاکنون درباره‌ی اعضای مربوط به هر وهله از کلاس‌ها صحبت کردیم؛ یعنی اعضایی که در زمان وهله‌سازی در دسترس خواهند بود. در واقع می‌توانیم اعضای استاتیک را نیز برای کلاس‌ها داشته باشیم. منظور از استاتیک این است که مقادیر یک عضوء استاتیک در وهله‌های مختلف یک شیء، متفاوت نیست. بلکه یک مقدار آن برای تمامی وهله‌ها به اشتراک گذاشته خواهد شد:
class Library {
    constructor(public name: string) {}
    
    static description: string = 'A source of knowledge';
}

let lib = new Library('New York Public Library');
console.log(lib.name); // available on instances of the class

console.log(Library.description);

Access Modifiers
با استفاده از Access Modifier می‌توانیم میدان دید یک پراپرتی و یا یک متد را برای مصرف کننده‌ی کلاس کنترل کنیم. TypeScript دارای سه Access Modifier است:
public: در حالت پیش‌فرض تمامی اعضای یک کلاس عمومی (public) هستند. در نتیجه لزومی به ذکر آن برای پراپرتی‌ها و متدها نیست. یک حالت استثناء، استفاده از Parameter properties است. در این حالت باید کلمه‌ی کلیدی public حتماً ذکر شود. 
private: برای محدود کردن دسترسی اعضای یک کلاس می‌توانید از کلمه‌ی کلیدی private استفاده کنید. در این‌حالت مصرف کننده‌ی کلاس به اعضای خصوصی (private) دسترسی نخواهد داشت. 
protected: این modifier نیز شبیه به private عمل می‌کند، با این تفاوت که توسط subclassهای مربوط به کلاس تعریف شده در آن نیز قابل دسترس است.


Inheritance
منظور از Inheritance یا ارث‌بری، اشتراک‌گذاری تعاریف یک کلاس برای یک یا چند sub-class است. فرض کنید یک کلاس با نام ReferenceItem با یکسری اعضای تعریف شده درون آن داریم و می‌خواهیم دو کلاس مشتق شده را از این کلاس تهیه کنیم. در این‌حالت کلاس ReferenceItem کلاس پایه (base class) و کلاس‌های مشتق شده از آن sub-class نامیده می‌شوند. بنابراین وهله‌های ایجاد شده از کلاس‌های مشتق شده دارای پراپرتی‌های کلاس پایه نیز خواهند بود. برای داشتن قابلیت ارث‌بری در TypeScript می‌توانیم به اینصورت عمل کنیم:
class ReferenceItem {
    title: string;
    printItem(): void { 
        // print something here 
    }
}

class Journal extends ReferenceItem {
    constructor() {
        super();
    }
    
    contributors: string[];
}
همانطور که مشاهده می‌کنید با استفاده از کلمه‌ی کلیدی extends توانسته‌ایم یک sub-class ایجاد کنیم. بنابراین وهله‌های کلاس Journal علاوه بر پراپرتی‌های خود (در اینجا contributors ) دارای پراپرتی title و همچنین متد printItem نیز هستند. نکته‌ایی که در اینجا وجود دارد این است که تمامی sub-classها یا کلاس‌های مشتق شده باید درون سازنده‌ی خود، تابع super را فراخوانی کنند؛ با اینکار سازنده‌ی کلاس پایه فراخوانی خواهد شد.
لازم به ذکر است که می‌توان متدهای کلاس پایه را درون کلاس‌های مشتق شده، override کرد. برای اینکار کافی است متد موردنظر در کلاس پایه را درون کلاس مشتق شده مجدداً تعریف کرده و منطق موردنظر را درون آن نوشت:
class Journal extends ReferenceItem {
    constructor() {
        super();
    }
    
    printItem(): void { 
        super.printItem();
        console.log('message from Journal');
    }
    
    contributors: string[];
}
با استفاده از super.printItem به کامپایلر TypeScript گفته‌ایم که تمامی کدهای درون متد printItem در کلاس پایه نیز اجرا شوند. اگر مایل بودید می‌توانید از آن صرفنظر کنید.

Abstract Classes 
کلاس‌های Abstract یک نوع خاص از کلاس‌ها هستند که نمی‌توان آنها را وهله‌سازی کرد. یعنی تنها برای تعریف کلاس‌های پایه از آنها استفاده خواهد شد. این نوع کلاس‌ها شبیه به اینترفیس‌ها هستند؛ اما ممکن است دارای پیاده‌سازی نیز باشند. در ادامه یک نمونه از abstract class را مشاهده می‌کنید:
abstract class ReferenceItem {
    private _publisher: string;
    static departement: string = 'Research';
    
    constructor(public title: string, protected year: number) {
        
    }
    
    printItem(): void {
        console.log('message from abstract class');
    } 
    
    get publisher(): string {
        return this._publisher.toUpperCase();
    }
    
    set publisher(newPublisher: string) {
        this._publisher = newPublisher;
    }
    
    abstract printCitation(): void;
}

class Encyclopedia extends ReferenceItem {
    
    constructor(newTitle: string, newYear, public edition: number) {
        super(newTitle, newYear);
    }
    
    printCitation(): void {
        console.log('message');
    }
}

let test = new Encyclopedia('WorldPerdia', 1900, 10);
test.printItem();
همانطور که مشاهده می‌کنید درون یک کلاس abstract می‌توانیم متدهای abstract را نیز داشته باشیم؛ یعنی تنها امضای متد را تعیین کرده و پیاده‌سازی آن را به کلاس‌های مشتق شده واگذار کنیم. 
اشتراک‌ها
آزادسازی خودکار منابع در TypeScript 5.2 با واژه‌ی کلیدی جدید using

A Look at TypeScript 5.2's New Keyword: using — using brings something akin to Python’s with context management into TypeScript with a way to automatically run a function when an object leaves scope. You could use it to shut down a database connection, close file handles, etc. 

آزادسازی خودکار منابع در TypeScript 5.2 با واژه‌ی کلیدی جدید using
اشتراک‌ها
همکاری تیم TypeScript و AngularJS

For the last several months, the Microsoft TypeScript and Google Angular teams have been working closely together. Today at ng-conf in Salt Lake City, the Angular and the TypeScript teams are unveiling the first fruits of that collaboration.  We’re excited to 

همکاری تیم TypeScript و AngularJS
اشتراک‌ها
اکستنشنی برای پیاده سازی CQRS , EventSourcing در Orleans

Orleankka is a functional extension for Microsoft Orleans framework. It provides a message-based API similar to Akka/ProtoActor, carefully layered on top of Microsoft Orleans (that's what in a name). Orleankka is an excellent choice for use-cases which can benefit from composable, uniform communication interface, such as CQRS, event-sourcing, FSM, etc.

اکستنشنی برای پیاده سازی CQRS , EventSourcing در Orleans
نظرات مطالب
نوع‌های نال نپذیر در TypeScript
یک نکته‌ی تکمیلی: اضافه شدن strictPropertyInitialization به TypeScript 2.7

در نگارش 2.7 اگر یک چنین تعریفی را داشته باشید:
export class MovieComponent {

  @Input() movie: Movie;

}
خطای زیر را دریافت خواهید کرد:
Error! Property movie has no initializer and is not assigned directly in the constructor.
یک روش برطرف کردن این خطا، نال‌پذیر تعریف کردن این خاصیت و سپس مقدار دهی اولیه‌ی به آن است:
@Input() movie: Movie | null = null;
و یا در مثال زیر می‌توان مشخص کرد که baz می‌تواند undefined هم باشد:
class C {
    baz: boolean | undefined;
}
روش دیگر، مقدار دهی اولیه، حین تعریف یک خاصیت است:
class C {
    bar = "hello";
}
و یا می‌توان این بررسی را به صورت زیر خاموش کرد:
class C {
    foo!: number;

    ngOnInit() {
        this.foo = 0;
    }
}
با استفاده از عملگر ! به کامپایلر اعلام می‌کنیم که این خاصیت حتما قرار است توسط روشی کمکی مقدار دهی اولیه شود و نال یا بدون مقدار نیست و استفاده‌ی از آن در این کلاس امن است.
مطالب
بررسی الگوی Visitor در جاوا اسکریپت
این الگو اجازه‌ی تعریف کردن عملیاتی جدید را برای مجموعه‌ای از شیء‌ها، بدون تغیر دادن ساختار خود شیء‌ها، میدهد. همچنین اجازه‌ی جدا کردن کلاس را از منطقی که کلاس  پیاده سازی می‌کند، به ما میدهد.
عملیات بیشتری می‌توانند در شیء Visitor کپسوله سازی شوند. شیء‌ها می‌توانند یک متد visit داشته باشند که یک شیء Visitor را دریافت می‌کند. Visitor می‌تواند تغییرات مورد نیاز را ایجاد کند و عملیاتی را بر روی شیء‌هایی که دریافت کرده‌است، انجام دهد.

این الگو به توسعه دهندگان این اجازه را میدهد که کتابخانه‌ها (libraries)، فریم ورک‌ها (frameworks) و ... را گسترش دهند.


مثال: 

class Visitor {
    visit(item){}
}

class BookVisitor extends Visitor {
    visit(book) {
        var cost=0; 
        if(book.getPrice() > 50) 
        { 
            cost = book.getPrice()*0.50 
        } 
        else{
            cost = book.getPrice()
        }     
        console.log("Book name: "+ book.getName() + "\n" + "ID: " + book.getID() + "\n" + "cost: "+ cost); 
        return cost; 
    }
}

class Book{
    constructor(id,name,price){
        this.id = id
        this.name = name
        this.price = price
    }
    getPrice(){
        return this.price
    }
    getName(){
        return this.name
    }
    getID(){
        return this.id
    }
    accept(visitor){
        return visitor.visit(this)
    }
}

var visitor = new BookVisitor()
var book1 = new Book("#1234","lordOftheRings",80)
book1.accept(visitor)

در مثال بالا ما یک کتابفروشی داریم. کلاس Book برای نشان دادن یک کتاب در فروشگاه استفاده شده‌است. این کلاس همانند زیر تعریف شده‌است: 
class Book{
    constructor(id,name,price){
        this.id = id
        this.name = name
        this.price = price
    }
    //code...
}

یک کتاب خصوصیات زیر را دارد: 
  • id
  • name
  • price

هم چنین شامل توابع زیر می‌باشد:
getPrice(){
    return this.price
}

getName(){
    return this.name
}

getID(){
    return this.id
}

متد getPrice ، قیمت را برگشت میدهد، getName ، نام را برگشت میدهد و getID، شناسه‌ی کتاب را برگشت میدهد.

اکنون کتابفروشی یک تخفیف را برای کتاب‌هایی که هزینه‌ی آن‌ها بیشتر از 50 دلار است، معرفی می‌کند. در ادامه، می‌خواهیم یک عملیات دیگر را انجام دهیم و تخفیف را بر روی آن‌ها پیاده سازی کنیم. در اینجا از الگوی visitor استفاده خواهیم کرد. ما یک Visitor را معرفی می‌کنیم که کتابها را بازدید خواهد کرد و قیمت آن‌ها را به‌روزرسانی می‌کند. بنابراین شیء‌های کتاب باید تابعی داشته باشند که اجازه دهد visitor، آنها را بازدید (visit) کند و عملیات مد نظر را بر روی آن‌ها انجام دهد. برای این منظور، یک متد به نام accept  در کلاس Book  تعریف کرده‌ایم:
 
accept(visitor){
    return visitor.visit(this)
}

متد accept  یک شیء visitor را به عنوان یک آرگومان دریافت می‌کند و به آن اجازه میدهد که با فراخوانی کردن تابع visit خودش، کتاب جاری را بازدید (visit) کند (this اشاره به کتاب جاری دارد) .

اکنون اجازه دهید نگاهی به کلاس Visitor  داشته باشیم: 
class Visitor {
   visit(item){}
}

این کلاس، یک تابع به نام visit دارد و itemی را که می‌خواهد بازدید (visit ) کند، به عنوان پارامتر دریافت می‌کند. در این سناریو، می‌خواهیم که کتاب‌ها را بازدید (visit ) کنیم. از این رو، در ابتدا یک کلاس را به نام BookVisitor تعریف می‌کنیم که کلاس Visitor را extend می‌کند: 

class BookVisitor extends Visitor {
   visit(book) {
      var cost=0; 
      if(book.getPrice() > 50) 
      { 
         cost = book.getPrice()*0.50 
      } 
      else{
         cost = book.getPrice()
      }     
      console.log("Book name: "+ book.getName() + "\n" + "ID: " + book.getID() + "\n" + "cost: "+ cost); 
      return cost; 
   }
}

تابع visit، قیمت کتابی را که دارد بازدید می‌کند، بررسی می‌کند. اگر بزرگتر از 50 باشد، 50 درصد تخفیف را بر روی آن اعمال می‌کند؛ در غیر این صورت، قیمت به حالت قبلی خودش باقی می‌ماند. 

چه زمانی از این الگو استفاده کنیم:

  1. زمانیکه نیاز است عملیاتی مشابه، بر روی شیء‌های متفاوتی از یک data structure  انجام شود. 
  2. زمانیکه نیاز است عملیاتی خاص، بر روی شیء‌های متفاوتی از data structure انجام شود. 
  3. زمانیکه می‌خواهید توسعه پذیری را برای کتابخانه‌ها (libraries) یا فریم ورک‌ها (frameworks) اضافه کنید.
اشتراک‌ها
استفاده از Web Worker ها در AngularJs

Using Web Workers, we can run JavaScript processes concurrently (or at least, as close to concurrently as this language allows). The primary benefit of this approach is to handle the manipulation of data in background threads without interfering with the user-interface. 

استفاده از Web Worker ها در AngularJs