diff --git a/lodash-decorators/lodash-decorators-tests.ts b/lodash-decorators/lodash-decorators-tests.ts
new file mode 100644
index 000000000..60a659c8d
--- /dev/null
+++ b/lodash-decorators/lodash-decorators-tests.ts
@@ -0,0 +1,370 @@
+///
+///
+
+//
+// With Arguments
+//
+
+import { after, debounce, memoize, curry } from 'lodash-decorators'
+
+class Person {
+ firstName: string;
+ lastName: string;
+ constructor(firstName: string, lastName: string) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ @after(3)
+ @debounce(100)
+ getFullName(): string {
+ return `${this.firstName} ${this.lastName}`
+ }
+
+ @curry(2)
+ @memoize()
+ doSomeHeavyProcessing(arg1: any, arg2: any) {
+ }
+}
+
+//
+// Without Arguments
+//
+
+import { tap } from 'lodash-decorators'
+
+class Person2 {
+ firstName: string;
+ lastName: string;
+ constructor(firstName?: string, lastName?: string) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ @once
+ getFullName(): string {
+ return `${this.firstName} ${this.lastName}`
+ }
+
+ @tap
+ popIt(list: number[]): void {
+ list.pop();
+ }
+}
+
+const person2 = new Person2();
+
+person2.popIt([1, 2, 3]); //=> [1, 2]
+
+//
+// Partials
+//
+
+import { partial, wrap } from 'lodash-decorators'
+
+class Person3 {
+ firstName: string;
+ lastName: string;
+ constructor(firstName?: string, lastName?: string) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ getName(type: string) {
+ return type === 'firstName' ? this.firstName : this.lastName
+ }
+
+ @partial('getName', 'firstName')
+ getFirstName(): string { return null; }
+
+ @partial('getName', null)
+ getLastName(): string { return null; }
+
+ @wrap('getName')
+ getUpperCaseName(fn: () => string): string {
+ return fn().toUpperCase();
+ }
+}
+
+//by .d.ts author: a workaround to ensure type
+interface Person3Ex extends Person3 {
+ getUpperCaseName(): string;
+}
+
+const person3 = new Person3('Joe', 'Smith') as Person3Ex;
+
+person3.getFirstName(); // 'Joe'
+person3.getLastName(); // 'Smith'
+person3.getUpperCaseName(); // JOE SMITH
+
+//
+// Composition
+//
+
+//import { kebabCase } from 'lodash';
+import * as _ from 'lodash';
+
+class Person4 {
+ firstName: string;
+ lastName: string;
+ constructor(firstName?: string, lastName?: string) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ getName(): string {
+ return `${this.firstName} ${this.lastName}`;
+ }
+
+ @compose(_.kebabCase, 'getName')
+ logName(name: string): void {
+ console.log(name);
+ }
+}
+
+//by .d.ts author: a workaround to ensure type
+interface Person4Ex extends Person4 {
+ logName(): void;
+}
+
+const person4 = new Person4('Joe', 'Smith') as Person4Ex;
+
+person4.logName(); // joe-smith
+
+//
+// Instance Decorators
+//
+
+class Person5 {
+
+ @curry(2) // <= prototype decorator
+ @debounce(100) // <= instance decorator
+ getName() {} //=> Throws an error. (╯°□°)╯︵ ┻━┻
+
+ @debounce(100) // <= instance decorator
+ @curry(2) // <= prototype decorator
+ getName2() {} //=> All is well :)
+}
+
+//
+// Getters and Setters
+//
+
+import { once, compose } from 'lodash-decorators'
+
+function alwaysArray(value: string|string[]): string[] {
+ return Array.isArray(value) ? value : _.isUndefined(value) ? [] : [value];
+}
+
+class Person6 {
+ constructor() {}
+ private nameList: string[];
+
+ //TODO: So far, TypeScript doesn't allow to put multiple decoratoes on set/get accessors.
+ // see https://github.com/Microsoft/TypeScript/issues/2249#issuecomment-141684146
+ //@once.get
+ get names(): string[] {
+ //MEMO: Resolve type inconsistency
+ return [this.nameList.join(' ')];
+ //MEMO: Original expression in repo
+ //return this.nameList.join(' ');
+ }
+
+ @compose.set(alwaysArray)
+ set names(names: string[]) {
+ this.nameList = names;
+ }
+}
+
+//by .d.ts author: a workaround to ensure type
+interface Person6Alt {
+ names: string[]|string;
+}
+
+const person6 = new Person6();
+
+// nameList will always be an array.
+person6.names = undefined; //=> []
+(person6 as Person6Alt).names = 'Joe'; //=> ['Joe']
+person6.names = ['Jim']; //=> ['Jim']
+
+//
+// Bind
+//
+
+import { bind } from 'lodash-decorators'
+
+class Person7 {
+ firstName: string;
+ lastName: string;
+ constructor(firstName: string, lastName: string) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ @bind()
+ getName(): string {
+ return `${this.firstName} ${this.lastName}`;
+ }
+
+ // It can also function as a partial
+ @bind('Joe')
+ getUpperCaseName(name: string): string {
+ return name.toUpperCase();
+ }
+}
+
+//by .d.ts author: a workaround to ensure type
+interface Person7Ex extends Person7 {
+ getUpperCaseName(): string;
+}
+
+const person7 = new Person7('Joe', 'Smith') as Person7Ex;
+
+person7.getName.call(null); // Joe Smith
+person7.getUpperCaseName(); // JOE
+
+
+import { bindAll } from 'lodash-decorators'
+
+@bindAll()
+class Person8 {
+ firstName: string;
+ lastName: string;
+ constructor(firstName: string, lastName: string) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ getName() {
+ return `${this.firstName} ${this.lastName}`;
+ }
+}
+
+const person8 = new Person8('Joe', 'Smith');
+
+person8.getName.call(null); // Joe Smith
+
+//
+// Forcing Decorator on Prototype
+//
+
+import { throttle } from 'lodash-decorators';
+
+class Person9 {
+ @throttle(1000)
+ doStuff() {}
+
+ @throttle.proto(1000)
+ doStuffMore() {}
+}
+
+const person9_1 = new Person9();
+const person9_2 = new Person9();
+
+person9_1.doStuff(); //=> Both are called
+person9_2.doStuff();
+
+person9_1.doStuffMore();
+person9_2.doStuffMore();
+
+// Only one of these methods is actual invoked because throttle is applied to the prototype method
+// and not the instance method.
+
+//
+// Extensions
+//
+
+import { deprecated } from 'lodash-decorators/extensions'
+
+// This is applied globally.
+deprecated.methodAction = fn => console.log(`Don't use ${fn.name}!`);
+
+@deprecated
+class Person10 {
+ constructor() {}
+}
+
+class OtherPerson {
+ @deprecated
+ fn() {}
+}
+
+let person10 = new Person10(); //=> Warning!
+
+let otherPerson = new OtherPerson();
+otherPerson.fn(); //=> Don't use fn!
+
+
+//
+// https://github.com/steelsojka/lodash-decorators/tree/master/src/extensions
+//
+
+import { Writable, ReturnsArg } from 'lodash-decorators/extensions';
+
+class Person11 {
+ constructor() {}
+
+ @Writable(false)
+ getName() {}
+
+ @ReturnsArg(1)
+ doSomething(x: any, y: any, z: any) {
+ // Do something here
+ }
+}
+
+//
+// https://github.com/steelsojka/lodash-decorators/tree/master/src/validate
+//
+
+import { Validate } from 'lodash-decorators/validate';
+
+class Person12 {
+ name: string;
+ constructor() {}
+
+ @Validate(_.isString)
+ setName(name: any) {
+ this.name = name as string;
+ }
+}
+
+class Person13 {
+ name: string;
+ age: number;
+ constructor() {}
+
+ @Validate(
+ _.isString,
+ [_.isNumber, _.partial(_.lt, 10) as ((_: any) => boolean)]
+ )
+ setData(name: any, age: any) {
+ this.name = name as string;
+ this.age = age as number;
+ }
+}
+
+const person13 = new Person13();
+
+person13.setData('test', 5); //=> TypeError
+person13.setData('test', 12); //=> Valid
+
+
+//
+// Additional typings
+//
+
+import { validateReturn } from 'lodash-decorators/validate';
+
+class Calc {
+ @validateReturn((c: number) => c > 0)
+ add(a: number, b: number): number {
+ return a + b;
+ }
+
+ @validateReturn([c => c > 0])
+ mul(a: number, b: number): number {
+ return a + b;
+ }
+}
diff --git a/lodash-decorators/lodash-decorators-tests.ts.tscparams b/lodash-decorators/lodash-decorators-tests.ts.tscparams
new file mode 100644
index 000000000..3f0863ac6
--- /dev/null
+++ b/lodash-decorators/lodash-decorators-tests.ts.tscparams
@@ -0,0 +1 @@
+--experimentalDecorators --noImplicitAny --target ES5
diff --git a/lodash-decorators/lodash-decorators.d.ts b/lodash-decorators/lodash-decorators.d.ts
new file mode 100644
index 000000000..ac01c5cf6
--- /dev/null
+++ b/lodash-decorators/lodash-decorators.d.ts
@@ -0,0 +1,272 @@
+// Type definitions for lodash-decorators 1.0.5
+// Project: https://github.com/steelsojka/lodash-decorators
+// Definitions by: Qubo
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+
+declare module "lodash-decorators" {
+ // Originally copied from ../node_modules/typescript/lib/lib.es6.d.ts
+ export interface ClassDecorator {
+ (target: TFunction): TFunction|void;
+ }
+ export interface PropertyDecorator {
+ (target: Object, propertyKey: string | symbol): void;
+ }
+ export interface MethodDecorator {
+ (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void;
+ }
+ export interface ParameterDecorator {
+ (target: Object, propertyKey: string | symbol, parameterIndex: number): void;
+ }
+
+ export interface TypedMethodDecorator {
+ (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void;
+ }
+
+ export interface MethodDecoratorWithAccessor extends MethodDecorator, Accessor {
+ }
+
+ export interface Accessor {
+ set: T;
+ get: T;
+ proto: T;
+ }
+
+ export interface DebounceDecorator {
+ (wait: number, options?: _.DebounceSettings): MethodDecorator;
+ }
+ export interface ThrottleDecorator {
+ (wait: number, options?: _.ThrottleSettings): MethodDecorator;
+ }
+ export interface MemoizeDecorator {
+ (resolver?: Function): MethodDecorator;
+ }
+ export interface AfterDecorator {
+ (n: number): MethodDecorator;
+ }
+ export interface BeforeDecorator {
+ (n: number): MethodDecorator;
+ }
+ export interface AryDecorator {
+ (n: number): MethodDecorator;
+ }
+ export interface CurryDecorator {
+ (arity?: number): MethodDecorator;
+ }
+ export interface CurryRightDecorator {
+ (arity?: number): MethodDecorator;
+ }
+ export interface RestParamDecorator {
+ (start?: number): MethodDecorator;
+ }
+ export interface PartialDecorator {
+ (func: Function|string, ...args: any[]): MethodDecorator;
+ }
+ export interface WrapDecorator {
+ (wrapper: ((func: Function, ...args: any[]) => any)|string): MethodDecorator;
+ }
+ export interface ComposeDecorator {
+ (...funcs: (Function|string)[]): MethodDecorator;
+ }
+ export interface DelayDecorator {
+ (wait: number, ...args: any[]): MethodDecorator;
+ }
+ export interface DeferDecorator {
+ (...args: any[]): MethodDecorator;
+ }
+ export interface BindDecorator {
+ (): TypedMethodDecorator<(() => R)>;
+ (param1?: T1):
+ TypedMethodDecorator<((param1: T1) => R)>;
+ (param1?: T1, param2?: T2):
+ TypedMethodDecorator<((param1: T1, param2: T2) => R)>;
+ (param1?: T1, param2?: T2, param3?: T3):
+ TypedMethodDecorator<((param1: T1, param2: T2, param3: T3) => R)>;
+ (param1?: T1, param2?: T2, param3?: T3, param4?: T4):
+ TypedMethodDecorator<((param1: T1, param2: T2, param3: T3, param4: T4) => R)>;
+ (param1?: T1, param2?: T2, param3?: T3, param4?: T4, param5?: T5):
+ TypedMethodDecorator<((param1: T1, param2: T2, param3: T3, param4: T4, param5: T5) => R)>;
+ (param1?: T1, param2?: T2, param3?: T3, param4?: T4, param5?: T5, param6?: T6):
+ TypedMethodDecorator<((param1: T1, param2: T2, param3: T3, param4: T4, param5: T5, param6: T6) => R)>;
+ }
+ export interface BindAllDecorator {
+ (...methodNames: string[]): ClassDecorator;
+ }
+ export interface ModArgsDecorator {
+ (...transforms: Function[]): MethodDecorator;
+ }
+
+ export const debounce: DebounceDecorator & Accessor;
+ export const Debounce: DebounceDecorator & Accessor;
+
+ export const throttle: ThrottleDecorator & Accessor;
+ export const Throttle: ThrottleDecorator & Accessor;
+
+ export const memoize: MemoizeDecorator & Accessor;
+ export const Memoize: MemoizeDecorator & Accessor;
+
+ export const after: AfterDecorator & Accessor;
+ export const After: AfterDecorator & Accessor;
+
+ export const before: BeforeDecorator & Accessor;
+ export const Before: BeforeDecorator & Accessor;
+
+ export const ary: AryDecorator & Accessor;
+ export const Ary: AryDecorator & Accessor;
+
+ export const curry: CurryDecorator & Accessor;
+ export const Curry: CurryDecorator & Accessor;
+
+ export const curryRight: CurryRightDecorator & Accessor;
+ export const CurryRight: CurryRightDecorator & Accessor;
+
+ export const restParam: RestParamDecorator & Accessor;
+ export const RestParam: RestParamDecorator & Accessor;
+
+ export const partial: PartialDecorator & Accessor;
+ export const Partial: PartialDecorator & Accessor;
+
+ export const partialRight: PartialDecorator & Accessor;
+ export const PartialRight: PartialDecorator & Accessor;
+
+ export const wrap: WrapDecorator & Accessor;
+ export const Wrap: WrapDecorator & Accessor;
+
+ export const compose: ComposeDecorator & Accessor;
+ export const Compose: ComposeDecorator & Accessor;
+
+ export const flow: ComposeDecorator & Accessor;
+ export const Flow: ComposeDecorator & Accessor;
+
+ export const flowRight: ComposeDecorator & Accessor;
+ export const FlowRight: ComposeDecorator & Accessor;
+
+ export const backflow: ComposeDecorator & Accessor;
+ export const Backflow: ComposeDecorator & Accessor;
+
+ export const delay: DelayDecorator & Accessor;
+ export const Delay: DelayDecorator & Accessor;
+
+ export const defer: DeferDecorator & Accessor;
+ export const Defer: DeferDecorator & Accessor;
+
+ export const bind: BindDecorator & Accessor;
+ export const Bind: BindDecorator & Accessor;
+
+ export const bindAll: BindAllDecorator;
+ export const BindAll: BindAllDecorator;
+
+ export const modArgs: ModArgsDecorator & Accessor;
+ export const ModArgs: ModArgsDecorator & Accessor;
+
+ export const once: MethodDecoratorWithAccessor;
+ export const Once: MethodDecoratorWithAccessor;
+
+ export const spread: MethodDecoratorWithAccessor;
+ export const Spread: MethodDecoratorWithAccessor;
+
+ export const rearg: MethodDecoratorWithAccessor;
+ export const Rearg: MethodDecoratorWithAccessor;
+
+ export const negate: MethodDecoratorWithAccessor;
+ export const Negate: MethodDecoratorWithAccessor;
+
+ export const tap: MethodDecoratorWithAccessor;
+ export const Tap: MethodDecoratorWithAccessor;
+}
+
+declare module "lodash-decorators/extensions" {
+ // Originally copied from ../node_modules/typescript/lib/lib.es6.d.ts
+ export interface ClassDecorator {
+ (target: TFunction): TFunction|void;
+ }
+ export interface PropertyDecorator {
+ (target: Object, propertyKey: string | symbol): void;
+ }
+ export interface MethodDecorator {
+ (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void;
+ }
+ export interface ParameterDecorator {
+ (target: Object, propertyKey: string | symbol, parameterIndex: number): void;
+ }
+
+ export interface DeprecatedDecorator extends MethodDecorator, ClassDecorator {
+ methodAction(fn: Function & { name: string }): void;
+ }
+
+ export const deprecated: DeprecatedDecorator;
+ export const Deprecated: DeprecatedDecorator;
+
+ export const writable: (writable?: boolean) => MethodDecorator;
+ export const Writable: (writable?: boolean) => MethodDecorator;
+
+ export const configurable: (configurable?: boolean) => MethodDecorator;
+ export const Configurable: (configurable?: boolean) => MethodDecorator;
+
+ export const returnsArg: (index?: number) => MethodDecorator;
+ export const ReturnsArg: (index?: number) => MethodDecorator;
+
+ export const enumerable: (enumerable?: boolean) => MethodDecorator;
+ export const Enumerable: (enumerable?: boolean) => MethodDecorator;
+
+ export const nonenumerable: MethodDecorator;
+ export const Nonenumerable: MethodDecorator;
+
+ export const nonconfigurable: MethodDecorator;
+ export const Nonconfigurable: MethodDecorator;
+
+ export const readonly: MethodDecorator;
+ export const Readonly: MethodDecorator;
+}
+
+declare module "lodash-decorators/validate" {
+ // Originally copied from ../node_modules/typescript/lib/lib.es6.d.ts
+ export interface ClassDecorator {
+ (target: TFunction): TFunction|void;
+ }
+ export interface PropertyDecorator {
+ (target: Object, propertyKey: string | symbol): void;
+ }
+ export interface MethodDecorator {
+ (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void;
+ }
+ export interface ParameterDecorator {
+ (target: Object, propertyKey: string | symbol, parameterIndex: number): void;
+ }
+
+ export interface TypedMethodDecorator {
+ (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void;
+ }
+
+ export interface Predicate {
+ (t: T): boolean;
+ }
+ type Predicates = Predicate|Predicate[];
+
+ export interface ValidateDecorator {
+ (p1: Predicates):
+ TypedMethodDecorator<((param1: T1) => R)>;
+ (p1: Predicates, p2?: Predicates):
+ TypedMethodDecorator<((param1: T1, param2: T2) => R)>;
+ (p1: Predicates, p2?: Predicates, p3?: Predicates):
+ TypedMethodDecorator<((param1: T1, param2: T2, param3: T3) => R)>;
+ (p1: Predicates, p2?: Predicates, p3?: Predicates, p4?: Predicates):
+ TypedMethodDecorator<((param1: T1, param2: T2, param3: T3, param4: T4) => R)>;
+ (p1: Predicates, p2?: Predicates, p3?: Predicates, p4?: Predicates, p5?: Predicates):
+ TypedMethodDecorator<((param1: T1, param2: T2, param3: T3, param4: T4, param5: T5) => R)>;
+ (p1: Predicates, p2?: Predicates, p3?: Predicates, p4?: Predicates, p5?: Predicates, p6?: Predicates):
+ TypedMethodDecorator<((param1: T1, param2: T2, param3: T3, param4: T4, param5: T5, param6: T6) => R)>;
+ }
+
+ export interface ValidateReturnDecorator {
+ (p1: Predicates): TypedMethodDecorator<((...args: any[]) => R)>;
+ }
+
+ export const validate: ValidateDecorator;
+ export const Validate: ValidateDecorator;
+
+ export const validateReturn: ValidateReturnDecorator;
+ export const ValidateReturn: ValidateReturnDecorator;
+}