打字稿:如何在没有TS2339错误的情况下将函数名称作为字符串

时间:2017-09-08 08:51:28

标签: function typescript object ecmascript-6 typescript2.0

我在Function.name documentation

中找到了以下示例
 private void grid_SelectionChanged(object sender, Telerik.UI.Xaml.Controls.Grid.DataGridSelectionChangedEventArgs e)
 {
     var cells = grid.SelectedItems;
     foreach (DataGridCellInfo cell in cells)
     {
         System.Diagnostics.Debug.WriteLine(cell.Value);
     } 
 }

打字稿中的问题(在此输入):

const o = {
  foo(){}
};
o.foo.name; // "foo";
当我想要检索时,会出现

const o: { foo: () => void } = { foo: () => { } }; o.foo.name; ,我将收到错误

  

TS2339(属性"名称"不存在)

我如何处理它,保持对象输入? 我想避免不得不施展财产" foo"比如o.foo.name

PS:用例是为了进一步重构而保持打字。例如,以下内容可以安全地重构:

(<any>o.foo).name

虽然这不是

spyOn(o, (<any>o.foo).name)

PS 2:似乎在ts:Get name of function in typescript

上检索函数名称可能会有问题

2 个答案:

答案 0 :(得分:2)

发布 ES2015 ,这:

const o: { foo: () => void } = {
    foo: () => { }
};
console.log(o.foo.name); 

应该可以正常工作。

Typescript Playground中查看它,并观察生成的JavaScript。您将看到您提到的foo示例的常见部分。

这是控制台,干净整洁:

enter image description here

在ES2015之前,这不起作用,如果不能选择针对ES2015后的选项,我认为你必须投出它。

答案 1 :(得分:2)

问题是此代码仅适用于较新版本的Javascript。如果将typescript编译器设置上的目标更改为es2015,问题就会消失。如果您定位es5,则该版本的定义不包含name属性,因为它可能无法在较旧的Javascript运行时上运行。

如果你可以定位es2015,那没关系,如果没有,你应该想出一个适合es5的不同解决方案。

如果您的目标是支持此属性的环境,但您还不信任所有功能的es2015实现,则可以添加Function接口中缺少的属性。在您的某个文件的顶层,您可以重新定义Function接口,这将合并到默认定义中,添加额外属性:

interface Function {
  /**
   * Returns the name of the function. Function names are read-only and can not be changed.
   */
  readonly name: string;
}