Skip to content

Commit 7264db6

Browse files
committed
feat: add built-in model property types typdef
Added typdef for: - Any - JSON - Text - GeoPoint - DateString Signed-off-by: Rifa Achrinza <[email protected]>
1 parent 9a58695 commit 7264db6

9 files changed

+270
-6
lines changed

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ export * from './types/observer-mixin';
3434
export * from './types/validation-mixin';
3535
export * from './types/inclusion-mixin';
3636
export * from './types/connector';
37+
export * from './types/geo';

package-lock.json

Lines changed: 7 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"mocha": "^8.4.0",
4848
"nyc": "^15.1.0",
4949
"should": "^13.2.3",
50-
"typescript": "^4.0.3"
50+
"typescript": "^4.4.3"
5151
},
5252
"dependencies": {
5353
"async": "^3.1.0",

types/__tests__/date-string.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { inspect } from 'util';
2+
import {DateString} from '../date-string';
3+
4+
let stringTypeGuard: string;
5+
6+
const dateString = new DateString('2020-01-01');
7+
DateString('2020-01-01');
8+
DateString(dateString);
9+
stringTypeGuard = dateString.toJSON().when;
10+
stringTypeGuard = dateString.toString();
11+
stringTypeGuard = dateString.inspect();
12+
stringTypeGuard = dateString[inspect.custom]();

types/__tests__/geopoint.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {GeoDistanceUnit, GeoPoint, filter, nearFilter} from '../geo';
2+
3+
let numberTypeGuard: number;
4+
5+
new GeoPoint(123, 456);
6+
new GeoPoint('123', 456);
7+
new GeoPoint(123, '456');
8+
new GeoPoint('123', '456');
9+
10+
new GeoPoint([123, 456]);
11+
new GeoPoint(['123', '456']);
12+
new GeoPoint(['123', 456]);
13+
new GeoPoint([123, '456']);
14+
15+
new GeoPoint({lat: 123, lng: 456});
16+
new GeoPoint({lat: '123', lng: 456})
17+
new GeoPoint({lat: 123, lng: '456'})
18+
new GeoPoint({lat: '123', lng: '456'});
19+
20+
numberTypeGuard = GeoPoint.distanceBetwen([123, 456], [123, 456]);
21+
numberTypeGuard = GeoPoint.distanceBetwen([123, 456], [123, 456], {type: GeoDistanceUnit.degrees});
22+
23+
const geoPoint = new GeoPoint(123, 456);
24+
numberTypeGuard = geoPoint.distanceTo([123, 456])
25+
numberTypeGuard = geoPoint.distanceTo([123, 456], {type: GeoDistanceUnit.degrees});

types/__tests__/types.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as buildModelTypes from '../types';
2+
import {ModelTypes, Type, Types} from '../types';
3+
4+
let stringTypeGuard: string;
5+
let voidTypeGuard: void;
6+
let jsonTypeGuard: Types.JSON;
7+
8+
stringTypeGuard = Types.JSON('arbitrary value');
9+
voidTypeGuard = Types.JSON(new Types.JSON('test'));
10+
jsonTypeGuard = new Types.JSON('test');
11+
const modelTypes: ModelTypes = {}
12+
buildModelTypes(modelTypes);
13+
voidTypeGuard = modelTypes.registerType({} as Type);
14+
voidTypeGuard = modelTypes.registerType({} as Type, ['custom name 1']);
15+
modelTypes.schemaTypes;

types/date-string.d.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {inspect} from 'util';
2+
3+
// @achrinza: One of the limitations of these definitions is that the class instance
4+
// isn't callable; Hence, changing the `value` class member must be done
5+
// directly. This is a TypeScript limitation as class constructors cannot
6+
// have a custom return value.
7+
export function DateString(value: DateString | string): DateString;
8+
export class DateString {
9+
private _when: string;
10+
private _date: Date;
11+
12+
get when(): string;
13+
set when(val: string);
14+
15+
constructor(value: string);
16+
17+
toString(): DateString['when'];
18+
toJSON(): {when: DateString['when']};
19+
inspect(): string;
20+
[inspect.custom]: DateString['inspect'];
21+
}

types/geo.d.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { Where } from "./query";
2+
3+
export function nearFilter(where: Where): false | GeoPointFilter[];
4+
5+
export function filter(rawResults: GeoPointRawResult[], filters: GeoPointFilter[]): GeoPointFilter;
6+
7+
export type GeoPointFilter = {
8+
near: GeoPoint | ConstructorParameters<typeof GeoPoint>;
9+
maxDistance: number;
10+
minDistance: number;
11+
unit: GeoDistanceUnit;
12+
mongoKey: string;
13+
key: string;
14+
}
15+
16+
export type GeoPointRawResult = {
17+
[key: string]: {
18+
lat: number;
19+
lng: number;
20+
}
21+
}
22+
23+
export class GeoPoint {
24+
lat: number;
25+
lng: number;
26+
27+
/**
28+
*
29+
* @example
30+
* ```typescript
31+
* new GeoPoint({
32+
* lat: 145,
33+
* lng: 96,
34+
* });
35+
* ```
36+
*
37+
* @example
38+
* ```typescript
39+
* new GeoPoint({
40+
* lat: '145',
41+
* lng: '96',
42+
* });
43+
* ```
44+
*
45+
* @param data
46+
*/
47+
constructor(data: {
48+
lat: string | number,
49+
lng: string | number,
50+
})
51+
52+
/**
53+
* @example
54+
* ```typescript
55+
* new GeoPoint('145,96');
56+
* ```
57+
*
58+
* @example
59+
* ```typescript
60+
* new GeoPoint('145 , 96');
61+
* ```
62+
*
63+
* @param data
64+
*/
65+
constructor(data: `${number},${number}`)
66+
67+
/**
68+
* @example
69+
* ```typescript
70+
* new GeoPoint([145, 96]);
71+
* ```
72+
*
73+
* @example
74+
* ```typescript
75+
* new GeoPoint(['145', '96']);
76+
* ```
77+
*
78+
* @param data
79+
*/
80+
constructor(data: [string | number, string | number])
81+
82+
/**
83+
* @example
84+
* ```typescript
85+
* new GeoPoint(145, 96);
86+
* ```
87+
*
88+
* @example
89+
* ```typescript
90+
* new GeoPoint('145', '96');
91+
* ```
92+
*
93+
* @param data
94+
*/
95+
constructor(lat: string | number, lng: string | number)
96+
97+
static distanceBetwen(
98+
a: GeoPoint | ConstructorParameters<typeof GeoPoint>,
99+
b: GeoPoint | ConstructorParameters<typeof GeoPoint>,
100+
options?: GeoDistanceOptions,
101+
): number;
102+
103+
distanceTo(
104+
point: GeoPoint | ConstructorParameters<typeof GeoPoint>,
105+
options?: GeoDistanceOptions,
106+
): number;
107+
108+
toString(): `$${number},${number}`;
109+
}
110+
111+
export type GeoDistanceOptions = {
112+
type: GeoDistanceUnit;
113+
}
114+
115+
export enum GeoDistanceUnit {
116+
'kilometers',
117+
'meters',
118+
'miles',
119+
'feet',
120+
'radians',
121+
'degrees',
122+
}

types/types.d.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import {DateString} from './date-string';
2+
import {GeoPoint} from './geo';
3+
4+
// @achrinza: The return value is a hack to inform TypeScript of function parameter mutations.
5+
// see: https://github.com/microsoft/TypeScript/issues/22865#issuecomment-725015710
6+
declare function registerModelTypes(modelTypes: registerModelTypes.ModelTypes): asserts modelTypes is registerModelTypes.BuiltModelTypes;
7+
8+
declare namespace registerModelTypes {
9+
// @achrinza: One of the limitations of these definitions is that the class instance
10+
// isn't callable; Hence, changing the `value` class member must be done
11+
// directly. This is a TypeScript limitation as class constructors cannot
12+
// have a custom return value.
13+
namespace Types {
14+
function Text<T extends unknown>(value: T): T extends Text ? void : T;
15+
class Text implements Type {
16+
value: Text;
17+
constructor(value: Text);
18+
toJSON(): Text;
19+
toObject(): Text;
20+
}
21+
22+
function JSON<T extends unknown>(value: T): T extends JSON ? void : T;
23+
class JSON implements Type {
24+
value: unknown;
25+
constructor(value: unknown)
26+
toJSON(): unknown;
27+
toObject(): unknown;
28+
}
29+
30+
31+
function Any<T extends unknown>(value: T): T extends Any ? void : T;
32+
class Any implements Type {
33+
value: unknown;
34+
constructor(value: unknown);
35+
toJSON(): unknown;
36+
toObject(): unknown;
37+
}
38+
}
39+
40+
interface ModelTypes {
41+
[type: string]: Type | unknown;
42+
}
43+
44+
interface Type {
45+
value: unknown;
46+
toJSON(): unknown;
47+
toObject(): unknown;
48+
}
49+
50+
interface BuiltModelTypes extends ModelTypes {
51+
schemaTypes: Record<string, Type> & {
52+
'String': String;
53+
'Number': Number;
54+
'Date': Date
55+
'DateString': DateString
56+
'Binary': Buffer;
57+
'Buffer': Buffer;
58+
'Array': Array<unknown>;
59+
'Object': Object;
60+
'GeoPoint': GeoPoint
61+
};
62+
registerType: (type: Type, names?: string[]) => void;
63+
}
64+
65+
}
66+
export = registerModelTypes;

0 commit comments

Comments
 (0)