Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic TypeScript definition #345

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
10 changes: 10 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ jobs:
- checkout
- yarn
- run: yarn lint

test-types:
executor: node
steps:
- checkout
- yarn
- run: yarn link
- run: yarn link microstates
- run: yarn test-types

coverage:
executor: node
Expand All @@ -49,6 +58,7 @@ workflows:
jobs:
- test
- lint
- test-types
- coverage


10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"module": "dist/microstates.es.js",
"unpkg": "dist/microstates.umd.js",
"browser": "dist/microstates.umd.js",
"types": "./types/microstates.d.ts",
"repository": "git+ssh://[email protected]/microstates/microstates.js.git",
"scripts": {
"start": "node repl.js",
Expand All @@ -35,13 +36,15 @@
"build": "rollup -c",
"bench": "node -r ./tests/setup benchmarks/index.js",
"prepare": "npm run build",
"prerelease": "npm test && npm run build"
"prerelease": "npm test && npm run build",
"test-types": "mocha -r ts-node/register types/*.test.ts"
},
"devDependencies": {
"@babel/core": "^7.1.6",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/preset-env": "^7.0.0",
"@babel/register": "^7.0.0",
"@types/mocha": "5.2.6",
"babel-eslint": "^10.0.1",
"benchmark": "^2.1.4",
"cli-table": "^0.3.1",
Expand All @@ -58,7 +61,10 @@
"rollup-plugin-filesize": "^6.0.0",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-replace": "^2.1.0",
"rxjs": "^6.2.1"
"rxjs": "^6.2.1",
"ts-expect": "^1.1.0",
"ts-node": "8.0.3",
"typescript": "^3.4.2"
},
"dependencies": {
"funcadelic": "^0.5.0",
Expand Down
127 changes: 127 additions & 0 deletions types/microstates.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
declare module 'microstates' {
export const Any: Constructor<Any>;
export interface Any {
set(value: any): Any;
state: any;
}

export const BooleanType: Constructor<BooleanType>;
export interface BooleanType {
set(value: boolean): BooleanType;
toggle(): BooleanType;
initialize(value: any): BooleanType;
state: boolean;
}

export const StringType: Constructor<StringType>;
export interface StringType {
concat(str: string): StringType;
set(value: string): StringType;
initialize(value: any): StringType;
state: string;
}

export const NumberType: Constructor<NumberType>;
export interface NumberType {
increment(step?: number): NumberType;
decrement(step?: number): NumberType;
set(value: number): NumberType;
initialize(value: any): NumberType;
state: number;
}

export const ObjectType: ObjectTypeConstructor & Constructor<ObjectType<Any>>;
interface ObjectType<T> extends Iterable<Entry<T>> {
entries: { [key: string]: T };
initialize(value: any): ObjectType<T>;
put(key: string, value: any): any;
delete(key: string): any;
assign(o: { [key: string]: any }): ObjectType<T>;
map(fn: (item: T) => any): ObjectType<T>;
filter(fn: (item: T) => boolean): ObjectType<T>;
}
interface ObjectTypeConstructor {
of<T>(constructor: Constructor<T>): Constructor<ObjectType<T>>;
}

export const ArrayType: ArrayTypeConstructor & Constructor<ArrayType<Any>>;
interface ArrayType<T> extends Iterable<T> {
length: number;
push(value: any): ArrayType<T>;
pop(): ArrayType<T>;
shift(): ArrayType<T>;
unshift(value: any): ArrayType<T>;
slice(start?: number, end?: number): ArrayType<T>;
sort(fn: (a: any, b: any) => number): ArrayType<T>;
filter(fn: (member: T) => boolean): ArrayType<T>;
map(fn: (member: T) => T): ArrayType<T>;
remove(item: any): ArrayType<T>;
clear(): ArrayType<T>;
initialize(value: any): ArrayType<T>;
set(value: any): ArrayType<T>;
}

interface ArrayTypeConstructor {
of<T>(constructor: Constructor<T>): Constructor<ArrayType<T>>;
}

export interface Entry<T> {
key: string;
value: T;
}

type PrimitiveDSL<T> = T extends Number
? NumberType
: T extends String
? StringType
: T extends Boolean
? BooleanType
: Any;

type ArrayDSL<T> = T extends (infer U)[] ? ArrayType<PrimitiveDSL<U>> : void;

type ObjectDSL<T> = T extends { [key: string]: infer U }
? U extends (infer V)[]
? ObjectType<ArrayType<PrimitiveDSL<V>>>
: ObjectType<PrimitiveDSL<U>>
: void;

type DSL<T> = T extends any[]
? ArrayDSL<T>
: T extends { [key: string]: infer U }
? ObjectDSL<T>
: PrimitiveDSL<T>;

interface Constructor<T> {
new (...args: any[]): T;
}

export function from<T>(value?: T): DSL<T> & Any;

export function create<T>(Type: Constructor<T>, value?: any): T & Any;

export function Store<T>(microstate: T, next: (state: T) => any): T & Any;

export function valueOf(target: any): any;

interface Query<T> extends Iterable<T> {
map<U>(fn: (t: T) => U): Query<U>;
filter(predicate: (item: T) => boolean): Query<T>;
reduce<R>(fn: (reduction: R, item: T) => R, initial: R): R;
}

export function query<T>(source: Iterable<T>): Query<T>;

export function map<A, B>(source: Iterable<A>, fn: (a: A) => B): Query<B>;

export function filter<A>(
source: Iterable<A>,
fn: (a: A) => boolean
): Query<A>;

export function reduce<A, B>(
source: Iterable<A>,
fn: (reduction: B, item: A) => B,
initial: B
): B;
}
Loading