Skip to content

Commit 5f33b9d

Browse files
committed
feat(jstree): typings for helper functions
1 parent 59071b7 commit 5f33b9d

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

src/index.d.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export const string = '';
2+
export const number = 0;
3+
export const boolean = false;
4+
5+
export class ExpectedReturnType<Right> {
6+
7+
}
8+
9+
type TypedClass<T> = { new(...args: any[]): T };
10+
11+
type GetBoolean<T> = { valueOf(): T & boolean };
12+
13+
type GetNumber<T> = { valueOf(): T, toExponential(): string };
14+
15+
type GetString<T> = { valueOf(): T, toLocaleLowerCase(): string };
16+
17+
type TypeOf<T> = TypedClass<T> | GetNumber<T> | GetString<T> | GetBoolean<T> | T;
18+
19+
declare function typ<T>(type: TypeOf<T>): T;
20+
21+
declare function fun<F>(func: F): F extends (...args: any) => void ? (...args: (Required<Parameters<F>> & Array<any>)) => void : ExpectedReturnType<void>;
22+
declare function fun<F, T>(type: TypeOf<T>, func: F): F extends (...args: any) => T ? (...args: (Required<Parameters<F>> & Array<any>)) => T : ExpectedReturnType<T>;
23+
24+
declare function cls<T>(prototype: T): T extends { constructor?(...args: any): void, [key: string]: unknown } ? new (...args: (Parameters<T['constructor']>)) => T : (new () => T);

src/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ export function fun(type, func) {
4343
let result;
4444
try {
4545
result = func.apply(this);
46+
47+
if (activeArgList && activeArgIndex < activeArgList.length) {
48+
throw new Error(`wrong argument length? expected: ${activeArgIndex} is: ${activeArgList.length}`);
49+
}
4650
} finally {
4751
activeArgList = undefined;
4852
activeArgIndex = -999;

test/types.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { assert } from 'chai';
2+
import { cls, fun, number, string, boolean, typ } from '../src';
3+
4+
describe('type safety tests', () => {
5+
6+
const string1 = typ(string);
7+
const string2 = typ(String);
8+
const string3 = typ('hallo');
9+
10+
const number1 = typ(number);
11+
const number2 = typ(Number);
12+
const number3 = typ(55);
13+
14+
const bool1 = typ(boolean);
15+
const bool2 = typ(Boolean);
16+
const bool3 = typ(true);
17+
18+
const C = cls({
19+
// h: typ(string),
20+
constructor: fun((hello = typ(string)) => {
21+
// this.h = hello;
22+
}),
23+
hallo: fun(string, (hello = typ(string)) => {
24+
25+
return hello;
26+
})
27+
});
28+
29+
const fun1 = fun(string, (str = typ(string), num = typ(number)) => {
30+
31+
return str;
32+
});
33+
34+
const c = new C('blub');
35+
36+
it('tests valid typings', () => {
37+
38+
const hello = fun1('hello', 2);
39+
40+
assert.equal(hello, 'hello');
41+
42+
const world = c.hallo('world');
43+
44+
assert.equal(world, 'world');
45+
});
46+
47+
it('throw errors on invalid typings', () => {
48+
const funBroken = fun(number, (str = typ(string), blub = typ(number)) => {
49+
50+
return 'bar';
51+
});
52+
53+
assert.throws(() => {
54+
funBroken('1', 2);
55+
});
56+
57+
assert.throws(() => {
58+
fun1('', 2, 3);
59+
});
60+
61+
assert.throws(() => {
62+
c.foo('');
63+
});
64+
65+
assert.throws(() => {
66+
const c2 = new C(1);
67+
});
68+
});
69+
});

0 commit comments

Comments
 (0)