diff --git a/scalike/scalike-tests.ts b/scalike/scalike-tests.ts
new file mode 100644
index 0000000000..6f2057468a
--- /dev/null
+++ b/scalike/scalike-tests.ts
@@ -0,0 +1,29 @@
+///
+
+import {Optional, Some, None, Try, Right, Left, Either, Future} from "scalike";
+
+// Optional
+Optional(1).map(x => x + 1); // Some(2)
+Optional(null).map(x => x + 1); // None
+Optional(undefined).map(x => x + 1); // None
+Optional(1).flatMap(x => Some(x + 1)).fold(0, x => x + 1); // 3
+
+// Try
+function something() { return 1; }
+Try(something); // Success(1)
+function throwError() { throw new Error; }
+Try(throwError); // Failure(Error)
+Try(() => 1).map(x => x + 1); // Success(2)
+
+// Either
+function validate(x: number): Either {
+ return x !== 1 ? Left('this is not 1') : Right(x);
+}
+validate(1).right().getOrElse(0); // 1
+validate(2).left().getOrElse("err"); // "this is not 1"
+
+// Future
+Future(something).map(x => x + 1); // Future(2)
+Future.successful(1).value; // Optional(Success(1)
+const fu = Future(something);
+Future.sequence([fu, fu, fu]); // Future([1, 1, 1])
diff --git a/scalike/scalike.d.ts b/scalike/scalike.d.ts
new file mode 100644
index 0000000000..1c14a1dc36
--- /dev/null
+++ b/scalike/scalike.d.ts
@@ -0,0 +1,271 @@
+// Type definitions for scalike API
+// Project: https://github.com/ryoppy/scalike-typescript
+// Definitions by: ryoppy
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+///
+
+declare module scalike {
+
+ export interface Either {
+ value: A | B;
+ isLeft: boolean;
+ isRight: boolean;
+ left(): LeftProjection;
+ right(): RightProjection;
+ fold(fa: (a: A) => X, fb: (b: B) => X): X;
+ swap(): Either;
+ }
+ export function Right(b: B): Either;
+ export function Left(a: A): Either;
+ export class LeftProjection {
+ private self;
+ constructor(self: Either);
+ toString(): string;
+ get(): A;
+ foreach(f: (a: A) => void): void;
+ getOrElse(x: X): A;
+ forall(f: (a: A) => boolean): boolean;
+ exists(f: (a: A) => boolean): boolean;
+ filter(f: (a: A) => boolean): Optional>;
+ map(f: (a: A) => X): Either;
+ flatMap(f: (a: A) => Either): Either;
+ toOptional(): Optional;
+ }
+ export class RightProjection {
+ private self;
+ constructor(self: Either);
+ toString(): string;
+ get(): B;
+ foreach(f: (b: B) => void): void;
+ getOrElse(x: X): B;
+ forall(f: (b: B) => boolean): boolean;
+ exists(f: (b: B) => boolean): boolean;
+ filter(f: (b: B) => boolean): Optional>;
+ map(f: (b: B) => X): Either;
+ flatMap(f: (a: B) => Either): Either;
+ toOptional(): Optional;
+ }
+
+ export interface Optional {
+ isEmpty: boolean;
+ nonEmpty: boolean;
+ get(): A;
+ getOrElse(a: B): A;
+ map(f: (a: A) => B): Optional;
+ fold(ifEmpty: B, f: (a: A) => B): B;
+ flatten(): Optional;
+ filter(f: (a: A) => boolean): Optional;
+ contains(b: B): boolean;
+ exists(f: (a: A) => boolean): boolean;
+ forall(f: (a: A) => boolean): boolean;
+ flatMap(f: (a: A) => Optional): Optional;
+ foreach(f: (a: A) => void): void;
+ orElse(ob: Optional): Optional;
+ apply1(ob: Optional, f: (a: A, b: B) => C): Optional;
+ apply2(ob: Optional, oc: Optional, f: (a: A, b: B, c: C) => D): Optional;
+ chain(ob: Optional): OptionalBuilder1;
+ }
+ export const None: Optional;
+ export function Optional(a: A): Optional;
+ export function Some(a: A): Optional;
+ export class OptionalBuilder1 {
+ private oa;
+ private ob;
+ constructor(oa: Optional, ob: Optional);
+ run(f: (a: A, b: B) => C): Optional;
+ chain(oc: Optional): OptionalBuilder2;
+ }
+ export class OptionalBuilder2 {
+ private oa;
+ private ob;
+ private oc;
+ constructor(oa: Optional, ob: Optional, oc: Optional);
+ run(f: (a: A, b: B, c: C) => D): Optional;
+ chain(od: Optional): OptionalBuilder3;
+ }
+ export class OptionalBuilder3 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ constructor(oa: Optional, ob: Optional, oc: Optional, od: Optional);
+ run(f: (a: A, b: B, c: C, d: D) => E): Optional;
+ chain(oe: Optional): OptionalBuilder4;
+ }
+ export class OptionalBuilder4 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ private oe;
+ constructor(oa: Optional, ob: Optional, oc: Optional, od: Optional, oe: Optional);
+ run(f: (a: A, b: B, c: C, d: D, e: E) => F): Optional;
+ chain(of: Optional): OptionalBuilder5;
+ }
+ export class OptionalBuilder5 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ private oe;
+ private of;
+ constructor(oa: Optional, ob: Optional, oc: Optional, od: Optional, oe: Optional, of: Optional);
+ run(f: (a: A, b: B, c: C, d: D, e: E, f: F) => G): Optional;
+ }
+
+ export interface Try {
+ isSuccess: boolean;
+ isFailure: boolean;
+ get(): A;
+ getError(): Error;
+ fold(fe: (e: Error) => B, ff: (a: A) => B): B;
+ getOrElse(a: B): A;
+ orElse(a: Try): Try;
+ foreach(f: (a: A) => void): void;
+ flatMap(f: (a: A) => Try): Try;
+ map(f: (a: A) => B): Try;
+ filter(f: (a: A) => boolean): Try;
+ toOptional(): Optional;
+ failed(): Try;
+ transform(fs: (a: A) => Try, ff: (e: Error) => Try): Try;
+ recover(f: (e: Error) => Optional>): Try;
+ apply1(ob: Try, f: (a: A, b: B) => C): Try;
+ apply2(ob: Try, oc: Try, f: (a: A, b: B, c: C) => D): Try;
+ chain(ob: Try): TryBuilder1;
+ }
+ export function Try(f: () => A): Try;
+ export function Success(a: A): Try;
+ export function Failure(e: Error): Try;
+
+ export class TryBuilder1 {
+ private oa;
+ private ob;
+ constructor(oa: Try, ob: Try);
+ run(f: (a: A, b: B) => C): Try;
+ chain(oc: Try): TryBuilder2;
+ }
+ export class TryBuilder2 {
+ private oa;
+ private ob;
+ private oc;
+ constructor(oa: Try, ob: Try, oc: Try);
+ run(f: (a: A, b: B, c: C) => D): Try;
+ chain(od: Try): TryBuilder3;
+ }
+ export class TryBuilder3 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ constructor(oa: Try, ob: Try, oc: Try, od: Try);
+ run(f: (a: A, b: B, c: C, d: D) => E): Try;
+ chain(oe: Try): TryBuilder4;
+ }
+ export class TryBuilder4 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ private oe;
+ constructor(oa: Try, ob: Try, oc: Try, od: Try, oe: Try);
+ run(f: (a: A, b: B, c: C, d: D, e: E) => F): Try;
+ chain(of: Try): TryBuilder5;
+ }
+ export class TryBuilder5 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ private oe;
+ private of;
+ constructor(oa: Try, ob: Try, oc: Try, od: Try, oe: Try, of: Try);
+ run(f: (a: A, b: B, c: C, d: D, e: E, f: F) => G): Try;
+ }
+
+ export interface Future {
+ getPromise(): Promise;
+ onComplete(f: (t: Try) => B): void;
+ isCompleted(): boolean;
+ value(): Optional>;
+ failed(): Future;
+ foreach(f: (a: A) => B): void;
+ transform(f: (t: Try) => Try): Future;
+ transform1(fs: (a: A) => B, ff: (e: Error) => Error): Future;
+ transformWith(f: (t: Try) => Future): Future;
+ map(f: (a: A) => B): Future;
+ flatMap(f: (a: A) => Future): Future;
+ filter(f: (a: A) => boolean): Future;
+ recover(f: (e: Error) => Optional): Future;
+ recoverWith(f: (e: Error) => Optional>): Future;
+ zip(fu: Future): Future<[A, B]>;
+ zipWith(fu: Future, f: (a: A, b: B) => C): Future;
+ fallbackTo(fu: Future): Future;
+ andThen(f: (t: Try) => B): Future;
+ apply1(ob: Future, f: (a: A, b: B) => C): Future;
+ apply2(ob: Future, oc: Future, f: (a: A, b: B, c: C) => D): Future;
+ chain(ob: Future): FutureBuilder1;
+ }
+ export function Future(f: Promise | (() => A)): Future;
+ export namespace Future {
+ function fromPromise(p: Promise): Future;
+ function unit(): Future;
+ function failed(e: Error): Future;
+ function successful(a: A): Future;
+ function fromTry(t: Try): Future;
+ function sequence(fus: Array>): Future>;
+ function firstCompletedOf(fus: Array>): Future;
+ function find(fus: Array>, f: (a: A) => boolean): Future>;
+ function foldLeft(fu: Array>, zero: B, f: (b: B, a: A) => B): Future;
+ function reduceLeft(fu: Array>, f: (b: B, a: A) => B): Future;
+ function traverse(fu: Array, f: (a: A) => Future): Future>;
+ }
+ export class FutureBuilder1 {
+ private oa;
+ private ob;
+ constructor(oa: Future, ob: Future);
+ run(f: (a: A, b: B) => C): Future;
+ chain(oc: Future): FutureBuilder2;
+ }
+ export class FutureBuilder2 {
+ private oa;
+ private ob;
+ private oc;
+ constructor(oa: Future, ob: Future, oc: Future);
+ run(f: (a: A, b: B, c: C) => D): Future;
+ chain(od: Future): FutureBuilder3;
+ }
+ export class FutureBuilder3 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ constructor(oa: Future, ob: Future, oc: Future, od: Future);
+ run(f: (a: A, b: B, c: C, d: D) => E): Future;
+ chain(oe: Future): FutureBuilder4;
+ }
+ export class FutureBuilder4 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ private oe;
+ constructor(oa: Future, ob: Future, oc: Future, od: Future, oe: Future);
+ run(f: (a: A, b: B, c: C, d: D, e: E) => F): Future;
+ chain(of: Future): FutureBuilder5;
+ }
+ export class FutureBuilder5 {
+ private oa;
+ private ob;
+ private oc;
+ private od;
+ private oe;
+ private of;
+ constructor(oa: Future, ob: Future, oc: Future, od: Future, oe: Future, of: Future);
+ run