如何在TypeScript中导出扩充类型(扩展名)

时间:2020-07-20 01:22:21

标签: typescript prototype

我已经增强了模仿C#LINQ的Array原型,这使我们能够将复杂的数组操作逻辑写入真正可读和可维护的代码中。当前在单个项目中使用时,效果很好:

ArrayExtensions.d.ts:

declare interface Array<T> {
    aggregate<TSource>(this: TSource[], seed: TSource, func: (accumulated: TSource, source: TSource) => TSource): TSource;
    all<T>(this: T[], predicate: (item: T) => boolean): boolean;
    any<T>(this: T[], predicate: (item: T) => boolean): boolean;
    append<T>(this: T[], value: T | T[]): T[];
    apply<T>(this: T[], action?: ((item: T) => void)): T[];
    average<T>(this: T[], callback: (item: T) => number | undefined): number | undefined;
    contains<T>(this: T[], value: T): boolean;
    count<T>(this: T[], predicate: (item: T) => boolean): number;
    distinct<T>(this: T[]): T[];
    empty<T>(this: T[]): boolean;
    exists<T>(this: T[], predicate: (item: T) => boolean): boolean;
    first<T>(this: T[], predicate?: ((item: T) => boolean)): T | undefined;
    groupBy<T>(this: T[], keyGetter: (item: T) => number): {[index: number]: T[]};
    groupBy<T>(this: T[], keyGetter: (item: T) => string): {[index: string]: T[]};
    hasOneOf(this: T[], values: T[]): boolean;
    insert<T>(this: T[], index: number, item: T): void;
    intersect<T>(this: T[], other: T[]): T[];
    last<T>(this: T[], predicate?: ((item: T) => boolean)): T | undefined;
    min<T, V>(this: T[], selector: (item: T) => V): {value: V, index: number, item: T};
    max<T, V>(this: T[], selector: (item: T) => V): {value: V, index: number, item: T};
    none(this: boolean[]): boolean;
    none<T>(this: T[], predicate: (item: T) => boolean): boolean;
    orderBy<T, G extends number | string | Date>(this: T[], keyGetter: (item: T) => G | undefined, order?: SortOrder): T[];
    orderByDescending<T, G extends number | string | Date>(this: T[], keyGetter: (item: T) => G | undefined): T[];
    select<T, U>(this: T[], predicate: (item: T, index: number) => U): U[];
    selectMany<TSource, TResult>(this: TSource[], selector: (item: TSource) => TResult[]): TResult[];
    sequenceEqual<T>(this: T[], other: T[]): boolean;
    single<T>(this: T[], predicate?: (item: T) => boolean): T | undefined;
    skip(this: T[], count: number): T[];
    sorted<T>(this: T[], order?: SortOrder): T[];
    sum(this: number[]): number;
    sum<T>(this: T[], callback: (item: T) => number | undefined): number;
    take<T>(this: T[], count: number): T[];
    union<T>(this: T[], other: T[]): void;
    where<T>(this: T[], predicate: (item: T) => boolean): T[];
}

ArrayExtensions.ts:

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

Object.defineProperty(Array.prototype, 'first', {
    value: function<T>(this: T[], predicate?: ((item: T) => boolean)): T | undefined {
        let index = this.firstIndex(predicate);
        return index != -1 ? this[index] : undefined;
    }
});

index.ts:

import "extensions/ArrayExtensions";

问题是我们需要将这些扩展放入我们在其他项目中重用的共享库中。我找不到导出TypeScript声明并使其他项目使用它们的方法。

我试图将其放入共享库的index.ts

export { Array } from "extensions/ArrayExtensions";

但是它说the module has no exported member Array.

我还尝试将声明直接放入共享库的index.ts中,而不是进行重新导出,但是从使用该库的项目中导入声明时,它说模块没有导出成员Array。您如何将一个项目的声明接口导出到另一个?

1 个答案:

答案 0 :(得分:1)

一个问题是,您正在考虑导入和导出模块成员,但实际上想要的是导入的副作用,就像项目的索引文件中定义附加成员的成员一样。这是因为您的扩展程序会修改全局值和全局类型,并且不会导出任何内容。

换句话说,任何需要访问这些成员的项目都应像这样导入它们

import "extensions/ArrayExtensions";

但是,您还有其他问题。您有一个声明文件ArrayExtensions.d.ts和一个源文件ArrayExtensions.ts并排放置,一个通过另一个引用

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

由此带来的潜在工具问题的数量,尤其是在共享库中,但是即使在单个项目中也是如此,以至于我在这里不做列举。拜托,请不要这样做。

将所有代码,声明和实现放入.ts文件中。并删除///<reference>!您绝对不需要也不需要任何东西。导入实现的任何人都应该获得相应的声明。

我不完全知道您的项目之间如何相互引用,或者您的构建过程是什么,所以您可能需要进行一些其他更改,但是我上面概述的内容很重要。

相关问题