How to use lodash.mixin in TypeScript How to use lodash.mixin in TypeScript typescript typescript

How to use lodash.mixin in TypeScript


See TypeScript docs on extending built-in types, which I think applies here as well. _ is defined as var _: _.LoDashStatic, and vars are not currently extendable.

The best way that I found to expose extensions is via a lodash-mixins.ts script that defines a new LoDashMixins interface (extending LoDashStatic), applies the mixins, and exports _ cast to the custom interface. This example defines a single mixin, but the idea is to add all your mixins to one script for easy importing.

import * as _ from 'lodash';import xdiff from './xdiff';interface LoDashMixins extends _.LoDashStatic {  xdiff<T>(array:T[], values:T[]): T[];}_.mixin({xdiff:xdiff});export default <LoDashMixins>_;

When you want to use the mixins, import './lodash-mixins' instead of 'lodash'. You now have compile-time visibility to all of the built-in functions, as well as your mixins.

import _ from './lodash-mixins';_.map([]); // built-in function still compiles_.xdiff([], []); // mixin function compiles too


You can do this.

// somewhere in your projectdeclare module _ {    interface LoDashStatic {        foo(value: string): number;    }}// extend it somewhere else declare module _ {    interface LoDashStatic {        bar(value: number);    }}

Test it out


You can do this using type erasure:

import _ = require('lodash');_.mixin(require('lodash-deep'));function deepSet(lodash: any, path: Array<string>, record: IFooRecord,         replacement: number): void {     lodash.deepSet(object, path, replacement); }interface IBarRecord {   bar: number;}interface IFooRecord {   foo: IBarRecord;}var subject: IFooRecord = {    foo: {      bar: 0   }};var replacement: number = 1;deepSet(_, ['foo', 'bar'], subject, replacement);

It's kind of a cludge, but your code will compile. You could also create your own proxy implementing the interface of the mixin and inject the lodash module instance into it to a achieve a more modular result:

import _ = require('lodash');_.mixin(require('lodash-deep'));    module 'lodash-deep' {   export class lodashDeep {     private _: any;      constructor(lodash?: any) {         if (!lodash) {            lodash = _;         }         this._ = lodash;      }      public deepSet(collection: any, path: any, value: any): void {         this._.deepSet(collection, path, value);      }      ...   }}