knockout.js - توابع بدون نام در تایپاسکریپت؟


در فایل knockout-2.2.d.ts ما داریم:

interface KnockoutObservableAny extends KnockoutObservableBase {

    (): any;
    (value): void;
}

من میفهمم که(): برای اعلام یک تابع با فهرست پارامتر خالی و نوع بازگشتی پس از دو نقطه استفاده میشود.

با این حال، من عدم وجود یک شناسه تابع در جلوی پرانتزها را نمیفهمم.

من انتظار چیزی شبیه به functionName(): any; را داشتم

این تابع «ناشناس» چه معنی دارد؟ چگونه میتوانم این تابع بدون نام را تفسیر کنم، ممنون.

پاسخ شماره ۱

رابط کاربری زیر تابعی را توصیف میکند که مانند یک گتر ویژگی عمل میکند، که یک الگوی رایج در دنیای جاوااسکریپت است:

interface Property {

     //getter
     (): string; 
}

//assume p: Property;
var value = p();  //The type of value will be a string.

همانطور که هست، رابط کاربری معادل این نوع تابعی است:

() => string

تفاوت این است که در مثال اول، میتوانید یک تابع را توصیف کنید که ویژگیها و اضافهبارهای اضافی دارد:

interface Property {
     //getter
     (): string; 

     //setter
     (value: string): void;

     //register for the change event.
     onPropertyChanged(handler: (newValue: string) => void): void;
}

//assume p: Property
var value = p();
p.onPropertyChanged(newValue => { value = newValue; })
p('newValue');  //Would set the value variable to 'newValue' 

Knockout از خصوصیات بایندینگ استفاده میکند که این الگو را دنبال میکنند، و نحو توضیح داده شده در اینجا و استفاده شده در مثال شما اجازه میدهد که این نوع الگو در TypeScript تعریف شود.

در مورد نام نداشتن تابع، خوب شما در حال اعلان یک رابط هستید. هر تابعی که رابط را برآورده کند نام متفاوتی خواهد داشت.

شخصاً، من دستور زبان را روشنتر مییافتم اگر از الگویی که در C# برای ایندکسورها استفاده میشود، پیروی میکرد:

//WARNING: Not valid TypeScript
interface Property {
     //getter
     this(): string; 

     //setter
     this(value: string): void;

     //register for the change event.
     onPropertyChanged(handler: (newValue: string) => void): void;
}

به نظر من، این نحو باعث میشود واضحتر شود که اعلام تابع، شیئی که رابط را پیادهسازی میکند توصیف میکند، نه یکی از متدهای آن.

امیدوارم مفید باشد.

پاسخ شماره ۲

اینها به عنوان امضاهای فراخوانی شناخته میشوند. همه interfaces هیچ تولید کد در زمان اجرا ندارند. آنها صرفاً وجود دارند تا به کامپایلر در بررسی نوع کمک کنند. به عنوان مثال.

interface Foo{
    ():number; // when you call it it returns a number
    (message:string):string; // when you call with a message it returns a string 
}

var foo:Foo; 

var num = foo();
var str = foo('Hello world!');