【问题标题】:Add method to Array in TypeScript 1.0在 TypeScript 1.0 中向数组添加方法
【发布时间】:2014-05-13 15:58:11
【问题描述】:

我正在尝试为 ASP.NET Ajax 库创建一个 TypeScript 1.0.2(VS 2013 Update 2 RTM)定义文件,但我对如何定义 MS Ajax 添加到的其他方法感到困惑基本 JS 类型,例如 Array。我创建了一个 AspNetAjax.d.ts 和一个 AspNetAjax-tests.ts 文件。当我尝试在测试文件中使用“add”方法时,我得到下面列出的编译器错误。

AspNetAjax.d.ts

interface Array<T> {
    add(array: T[], item: T): void;
}

AspNetAjax-tests.ts

///<reference path="AspNetAjax.d.ts" /> 

var a: string[] = ['a', 'b', 'c', 'd'];
Array.add(a, 'e');
console.log(a.toString());

错误 1 ​​'{ isArray(arg: any): boolean; 类型的值不存在属性 'add'原型:任何[]; (arrayLength?: number): any[]; (arrayLength: number): T[]; (...项目: T[]): T[];新的(数组长度?:数字):任何[];新的(数组长度:数字):T[];新的(...项目:T[]):T[]; }'。 c:\path\AspNetAjax-tests.ts 4 7 TypeScriptHTMLApp1

来自同一 d.ts 文件的其他定义在测试文件中有效,因此我知道该引用在物理上有效。 TypeScript 也不会抱怨我声明 d.ts 文件的方式(那里没有红色曲线)。

我知道这些其他问题,并且我认为我正在按照他们的建议进行操作,但似乎它们是从 2012 年末/2013 年初开始的,所以从那时起执行此操作的方式可能发生了变化?

Extending Array in TypeScript

Adding a property to Array in Typescript

How can I add a static method to an existing type?

我需要对 d.ts 进行编码,以便 .ts 文件中的代码能够正常工作。有什么想法吗?

【问题讨论】:

标签: webforms typescript


【解决方案1】:

您编写的代码将add 成员添加到数组instances,而不是内置的Array 对象。

Array 内置对象在 lib.d.ts 中第 1134 行附近定义:

declare var Array: {
    new (arrayLength?: number): any[];
    new <T>(arrayLength: number): T[];
    new <T>(...items: T[]): T[];
    (arrayLength?: number): any[];
    <T>(arrayLength: number): T[];
    <T>(...items: T[]): T[];
    isArray(arg: any): boolean;
    prototype: Array<any>;
}

如果您想将成员添加到Array,您可以修改 lib.d.ts 中出现的声明。

如果您认为使用 lib.d.ts 似乎是个坏主意,那是因为您不应该修改内置对象。无法确定您和其他人是否都认为您对具有完全不同行为的 Array.add 方法有一个好主意。

【讨论】:

  • 嗨瑞恩 - 非常感谢。你是对的:如果我将 .ts 文件更改为 a.add(a, 'e');,它确实可以毫无错误地编译。关于如何修改内置对象是你不应该做的事情,我完全同意你的看法。但是,ASP.NET Ajax library does it。理解这是“不好的”,编辑 lib.d.ts 是允许 TypeScript 从使用 Ajax 库并利用其“帮助程序”的旧 ASP.NET 站点编译代码的唯一方法吗?
【解决方案2】:

您可以利用 TypeScript 中的声明合并逻辑来扩展 Array,如下所示:

declare module Array{
    export var add:Function;
}

var a: string[] = ['a', 'b', 'c', 'd'];
Array.add(a, 'e'); // Okay now
console.log(a.toString());

【讨论】:

  • 感谢 Basarat,但我得到了一个“重复的标识符 'Array'”。 TypeScript 1.0 中的声明块出错。我想这与第三个链接问题中的错误相同。也许编辑 lib.d.ts 文件是目前唯一的方法。
  • 嗯,它在这里工作,在打字稿游乐场
  • 我还看到它在操场上工作(尽管它删除了 Array 上的其他属性,因此必须重新实现它们)。我在 VS 2013 Update 2(即 TS 1.0.1)中收到错误,在保存时编译以及命令行中的 tsc.exe 1.0.1.0。
【解决方案3】:

在@basarat 和@Ryan-Cavanaugh 的回答之间,我能够想出一个与 TypeScript 1.0 一起使用的对用户来说最可怕的解决方案,只要人们愿意接受修改内置JS 对象通常是个坏主意,所以如果在 TypeScript 中支持它有点尴尬也没关系。

假设我在内置 JS Array 对象上定义 ASP.NET AJAX 扩展

  • 我将在 d.ts 文件中声明一个名为 AspNetAjaxExtensions 的模块
  • 我将在该模块声明中创建一个非导出接口,名为JavaScriptArray&lt;T&gt;
  • 我将在该模块声明中创建一个导出接口,名为Array&lt;T&gt;,即extends JavaScriptArray&lt;T&gt;
  • 我会将 ArrayArray&lt;T&gt; 的所有定义从 TypeScript 附带的 lib.d.ts 复制到新的 JavaScriptArray&lt;T&gt; 接口中。
  • 然后我可以继续在新的Array&lt;T&gt; 接口中仅对扩展功能进行建模。

这对 d.ts 作者来说有点反 DRY,但实际上这些东西很少改变,从 lib.d.ts 复制的 JavaScriptArray&lt;T&gt; 中的内容是独立的。从技术上讲,甚至可以创建一个构建步骤来动态填充此界面。

对于用户,他们必须更改调用扩展 Array 对象的代码:

//will be an error in TypeScript 1.0
Array.add(x, 'thing');

到这里:

//This works in TypeScript 1.0 after importing the above-described d.ts file.
(<AspNetAjaxExtensions.Array<string>>Array).add(x, 'thing');

甚至可以用(&lt;AspNetAjaxExtensions.Array&lt;any&gt;&gt;Array).add( 查找+替换Array.add(

他们只需要在调用内置 Array 对象上的任何扩展方法时执行此操作(这将被 TypeScript 语法错误调用)。对普通数组方法的调用仍将使用 lib.d.ts 中的“普通”定义。

新 AspNetAjax.d.ts 文件示例:

declare module AspNetAjaxExtensions {

    /** This interface definition was copied from lib.d.ts */
    interface JavaScriptArray<T> {
        new (arrayLength?: number): any[];
        new <T>(arrayLength: number): T[];

        /* -- Snip out many copied and pasted lines of code from lib.d.ts -- */

    }

    /** JavaScript Array object as extended by ASP.NET Ajax */
    export interface Array<T> extends JavaScriptArray<T>  {

        /** Adds an element to the end of an Array object.  This function is static and is invoked without creating an instance of the object.
          http://msdn.microsoft.com/en-us/library/bb310854(v=vs.100).aspx
          @param array The array to add the item to.
          @param item The object to add to the array.
        */
        add(array: T[], item: T): void;

        /* -- etc... defining remaining extended methods -- */
    }
}

【讨论】:

  • 最好的解决方法,直到它们使合并声明的变量更易于使用或扩展。
猜你喜欢
  • 2017-11-14
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-21
  • 1970-01-01
相关资源
最近更新 更多