如何在支持链式操作的 TypeScript 中使用 Lodash 的 Mixins

5

我是一名帮助翻译文本的助手。

我在尝试使用Typescript扩展Lodash并添加自定义mixin时遇到了困难。

我的不成功尝试:

假设我使用mixin将一个新函数添加到Lodash中,代码如下:

//lodashMixins.ts

import * as _ from "lodash";

_.mixin({
  swap
});

function swap(array: Array<any>, index1: number, index2: number) {
    let temp = array[index1];
    array[index1] = array[index2];
    array[index2] = temp;
    return array;
}
import _ from "lodash";在其他文件中使用时,swap函数不可用。 部分成功的尝试: 之后我寻求了帮助,并且人们建议使用extend_.LoDashStatic,然后导出作为新扩展的interface_
之后,我进行了以下操作:
//lodashMixins.ts

import * as _ from "lodash";

interface LodashExtended extends _.LoDashStatic {
  swap(array: Array<any>, index1: number, index2: number): Array<any>;
}

_.mixin({
  swap
});

function swap(array: Array<any>, index1: number, index2: number) {
    let temp = array[index1];
    array[index1] = array[index2];
    array[index2] = temp;
    return array;
}

export default _ as LodashExtended;

并使用以下新的混合

//otherFile.ts

import _ from "./lodashMixins";

function someFn(){
    var array = [1,2,3,4]
    _.swap(array, 1, 2);
}

现在虽然可以正常工作,但是有两个问题
  1. 首先,新的swap函数无法使用lodash的链式语法(明确链接和隐式链接都不行)。

这意味着,如果我执行以下任何操作,typescript都会报错:

//otherFile.ts

import _ from "./lodashMixins";

function someFn(){
    var cantDothis = _.chain([1,2,3,4]).map(x=>x*x).swap(1,2).value();
    //[ts] Property 'swap' does not exist on type 'LoDashExplicitWrapper<number[]>'.

    var neitherThis = _([1,2,3,4]).map(x=>x*x).swap(1,2).value();
    //[ts] Property 'swap' does not exist on type 'LoDashImplicitWrapper<number[]>'.
}
  1. 我需要使用这个 丑陋的 import _ from "./lodashMixins"; 而不是标准的 import _ from "lodash";

请有人提供一个优雅的解决方案,可以提供typescript类型支持,同时进行链接,没有任何代码味道或丑陋。 谢谢。 :)

也许John-David Dalton可以帮忙。

1个回答

9

您正在寻找模块扩充。您可以通过重新定义并添加额外的方法来扩展现有模块中的接口。在这种情况下,您应该增强LoDashStatic以进行静态使用,并增强LoDashExplicitWrapper以进行链式使用。当您使用该模块时,您可以先导入lodash,然后导入包含swap的模块以获取其副作用(将该方法添加到lodash的副作用)。

// swap.ts
import * as _ from "lodash";


declare module "lodash" {
    interface LoDashStatic {
        swap<TValue>(array: Array<TValue>, index1: number, index2: number): TValue[];
    }
    interface LoDashExplicitWrapper<TValue> {
        swap(index1: number, index2: number): LoDashExplicitWrapper<TValue>;
    }
}

_.mixin({
    swap
});

function swap(array: Array<any>, index1: number, index2: number) {
    let temp = array[index1];
    array[index1] = array[index2];
    array[index2] = temp;
    return array;
}

//usage 
import * as _ from "lodash";
import "./swap"


console.log(_.chain([1,2,3,4]).map(x=>x*x).swap(1,2).map(x=> x * 2).value());

var array = [1,2,3,4]
console.log(  _.swap(array, 1, 2));

您可以在这里了解更多关于模块扩展的内容。


非常完美的回答,非常感谢你。 :) - pranavjindal999
1
非常有帮助!我还需要添加接口 LoDashImplicitWrapper,以便TS正确地对 _([1, 2, 3]).swap(0, 2).value() 进行类型标注。使用的版本为 TS v3.2.2 和 Lodash v4.17.11。 - tokland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接