打字稿中的无名函数?

时间:2014-01-31 21:56:44

标签: knockout.js typescript

在knockout-2.2.d.ts中我们有:

interface KnockoutObservableAny extends KnockoutObservableBase {

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

我理解():用于声明一个带有空参数列表的函数和冒号后的返回类型。

但是我不明白括号前面缺少功能标识符。

我原本期望像functionName():any;

这个“匿名”功能意味着什么?我如何解释这个无名函数,谢谢。

3 个答案:

答案 0 :(得分:2)

以下界面描述的功能类似于属性getter,这是JavaScript世界中的常见模式:

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;
}

在我看来,这种语法更清楚地表明函数声明描述了实现接口的对象,而不是其中一种方法。

希望有所帮助。

答案 1 :(得分:1)

这些称为呼叫签名。所有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!'); 

答案 2 :(得分:0)

TL; DR

interface SiblingMethods {
  [key: string]: (param: number) => string;
}

const methods: SiblingMethods = {
  dynamicInterface1(paramFor1: number) {
    return "dynamicInterface1";
  },

  dynamicInterface2(paramFor2: number) {
    return "dynamicInterface2";
  },
};

我希望创建一个允许使用任何属性名称的接口,但是该属性必须是仅接受特定参数并返回特定类型的函数。

不是很确定要谷歌搜索什么,但是经过一秒钟的思考之后最终得到了它。

interface ChannelMethods {
  [key: string]: (methods: ActionCable.CreateMixin, params?: any) => ActionCable.Channel;
}

这将允许函数返回名称无关紧要但必须遵守参数和返回类型的函数对象。

let cable: ActionCable.Cable;

export const ChannelFp = function(methods: ChannelMethods): ChannelMethods {
  if (!cable) cable = ActionCable.createConsumer(WEBSOCKET_HOST);
  return methods;
}

const PatientChannelFpMethods: ChannelMethods = {
  appointmentChannel(methods: ActionCable.CreateMixin, appointmentId: string) {
    return cable.subscriptions.create({
      channel: 'Patient::AppointmentChannel',
      appointment_id: appointmentId,
    }, methods);
  },
}

export const PatientChannelFp = function(): typeof PatientChannelFpMethods {
  return ChannelFp(PatientChannelFpMethods) as typeof PatientChannelFpMethods;
}