-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtests.ts
75 lines (48 loc) · 1.63 KB
/
tests.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { UnitsMeta, Units, Mul, Div, Unit, Inverse, Pure } from '.';
function check<T>(value: T) {}
function type<T>(): T { return (undefined as any) as T; }
type A = Unit<'A'>;
type B = Unit<'A'>;
type AB = Unit<'A'> & Unit<'B'>;
check<A>(type<Mul<A, Pure>>());
check<A>(type<Div<A, Pure>>());
check<Pure>(type<Mul<Pure, Pure>>());
check<Pure>(type<Div<Pure, Pure>>());
check<Pure>(type<Inverse<Pure>>());
check<Inverse<'A'> & Inverse<'B'>>(type<Inverse<AB>>());
export type TypedNumber<U extends Units> =
UnitsMeta<U> & {
plus(other: TypedNumber<U>): TypedNumber<U>;
mul<O extends Units>(other: TypedNumber<O>): TypedNumber<Mul<U, O>>;
div<O extends Units>(other: TypedNumber<O>): TypedNumber<Div<U, O>>;
}
export type Scalar<K extends string> = TypedNumber<{
[P in K]: 1;
}>;
const a = {} as Scalar<'A'>;
const b = {} as Scalar<'B'>;
const c = {} as Scalar<'C'>;
const d = {} as Scalar<'D'>;
const pure = {} as TypedNumber<Pure>;
check<unknown>(a.plus(a.mul(b)));
check<unknown>(a.plus(b));
check<unknown>(a.plus(a.mul(a)));
check<unknown>(a.plus(pure));
check<Scalar<'A'>>(a.plus(a));
check<Scalar<'A'>>(a.mul(b).div(b));
check<TypedNumber<{ A: 1, B: 1 }>>(a.mul(b));
check<Scalar<'D'>>(
((a.mul(b)).mul(c.mul(d))).div(b.mul(c).mul(a))
);
check<TypedNumber<{ A: 1, D: 1 }>>(
((a.mul(b)).mul(c.mul(d))).div(b.mul(c))
);
const foo: Scalar<'D'> = (
(a.mul(b)).mul(c.mul(d)))
.div(b.mul(c).mul(a));
type Speed = TypedNumber<Unit<'Distance'> & Inverse<'Time'>>;
const time = {} as TypedNumber<Unit<'Time'>>;
const dist = {} as TypedNumber<Unit<'Distance'>>;
let v: Speed;
v = time.div(dist); // err
v = dist.div(time);