I'm having trouble using Lodash with typescript when I'm trying to extend lodash with my custom mixins.
My unsuccessful attempt:
Lets say I add a new function to lodash using mixins as follows:
//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;
}
The function swap
is not available on _
if I import _ from "lodash";
in other files.
Partially successful attempt:
Then I looked for help, and people suggested to extend
_.LoDashStatic
and then export the _
as the new extended interface
.
Then I did following:
//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;
And using the new mixed-in as following:
//otherFile.ts
import _ from "./lodashMixins";
function someFn(){
var array = [1,2,3,4]
_.swap(array, 1, 2);
}
Now this works, but there are two issues:
- First that the new
swap
function is not working with lodash's chained syntax (neither with explicit chaining nor with implicit chaining).
which means, that typescript gets angry if I do any of the following:
//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[]>'.
}
- Second that I have to do this ugly
import _ from "./lodashMixins";
instead of standardimport _ from "lodash";
.
Someone please e up with an elegant solution that provides typescript type support while chaining without any code smell or ugliness.. Thanks. :)
May be John-David Dalton can help.
I'm having trouble using Lodash with typescript when I'm trying to extend lodash with my custom mixins.
My unsuccessful attempt:
Lets say I add a new function to lodash using mixins as follows:
//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;
}
The function swap
is not available on _
if I import _ from "lodash";
in other files.
Partially successful attempt:
Then I looked for help, and people suggested to extend
_.LoDashStatic
and then export the _
as the new extended interface
.
Then I did following:
//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;
And using the new mixed-in as following:
//otherFile.ts
import _ from "./lodashMixins";
function someFn(){
var array = [1,2,3,4]
_.swap(array, 1, 2);
}
Now this works, but there are two issues:
- First that the new
swap
function is not working with lodash's chained syntax (neither with explicit chaining nor with implicit chaining).
which means, that typescript gets angry if I do any of the following:
//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[]>'.
}
- Second that I have to do this ugly
import _ from "./lodashMixins";
instead of standardimport _ from "lodash";
.
Someone please e up with an elegant solution that provides typescript type support while chaining without any code smell or ugliness.. Thanks. :)
May be John-David Dalton can help.
Share Improve this question asked Apr 20, 2018 at 13:19 pranavjindal999pranavjindal999 3,0474 gold badges29 silver badges35 bronze badges1 Answer
Reset to default 9You are looking for module augmentation. You can extend interfaces in existing modules by redefining them and adding extra methods. In this case you should augment LoDashStatic
for static usage and LoDashExplicitWrapper
for chain usage. When you use the module, you can first import lodash
and then import the module containing swap
for its side effects (the side effect of adding the method to 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));
You can read more about module augmentation here