feat: add built-in model property types typdef

Added typdef for:
- Any
- JSON
- Text
- GeoPoint
- DateString

Signed-off-by: Rifa Achrinza <25147899+achrinza@users.noreply.github.com>
This commit is contained in:
Rifa Achrinza 2021-09-12 17:32:36 +08:00
parent e3448fad03
commit 816b948ab0
7 changed files with 262 additions and 0 deletions

1
index.d.ts vendored
View File

@ -34,3 +34,4 @@ export * from './types/observer-mixin';
export * from './types/validation-mixin';
export * from './types/inclusion-mixin';
export * from './types/connector';
export * from './types/geo';

View File

@ -0,0 +1,12 @@
import { inspect } from 'util';
import {DateString} from '../date-string';
let stringTypeGuard: string;
const dateString = new DateString('2020-01-01');
DateString('2020-01-01');
DateString(dateString);
stringTypeGuard = dateString.toJSON().when;
stringTypeGuard = dateString.toString();
stringTypeGuard = dateString.inspect();
stringTypeGuard = dateString[inspect.custom]();

View File

@ -0,0 +1,25 @@
import {GeoDistanceUnit, GeoPoint, filter, nearFilter} from '../geo';
let numberTypeGuard: number;
new GeoPoint(123, 456);
new GeoPoint('123', 456);
new GeoPoint(123, '456');
new GeoPoint('123', '456');
new GeoPoint([123, 456]);
new GeoPoint(['123', '456']);
new GeoPoint(['123', 456]);
new GeoPoint([123, '456']);
new GeoPoint({lat: 123, lng: 456});
new GeoPoint({lat: '123', lng: 456})
new GeoPoint({lat: 123, lng: '456'})
new GeoPoint({lat: '123', lng: '456'});
numberTypeGuard = GeoPoint.distanceBetwen([123, 456], [123, 456]);
numberTypeGuard = GeoPoint.distanceBetwen([123, 456], [123, 456], {type: GeoDistanceUnit.degrees});
const geoPoint = new GeoPoint(123, 456);
numberTypeGuard = geoPoint.distanceTo([123, 456])
numberTypeGuard = geoPoint.distanceTo([123, 456], {type: GeoDistanceUnit.degrees});

View File

@ -0,0 +1,15 @@
import * as buildModelTypes from '../types';
import {ModelTypes, Type, Types} from '../types';
let stringTypeGuard: string;
let voidTypeGuard: void;
let jsonTypeGuard: Types.JSON;
stringTypeGuard = Types.JSON('arbitrary value');
voidTypeGuard = Types.JSON(new Types.JSON('test'));
jsonTypeGuard = new Types.JSON('test');
const modelTypes: ModelTypes = {}
buildModelTypes(modelTypes);
voidTypeGuard = modelTypes.registerType({} as Type);
voidTypeGuard = modelTypes.registerType({} as Type, ['custom name 1']);
modelTypes.schemaTypes;

21
types/date-string.d.ts vendored Normal file
View File

@ -0,0 +1,21 @@
import {inspect} from 'util';
// @achrinza: One of the limitations of these definitions is that the class instance
// isn't callable; Hence, changing the `value` class member must be done
// directly. This is a TypeScript limitation as class constructors cannot
// have a custom return value.
export function DateString(value: DateString | string): DateString;
export class DateString {
private _when: string;
private _date: Date;
get when(): string;
set when(val: string);
constructor(value: string);
toString(): DateString['when'];
toJSON(): {when: DateString['when']};
inspect(): string;
[inspect.custom]: DateString['inspect'];
}

122
types/geo.d.ts vendored Normal file
View File

@ -0,0 +1,122 @@
import { Where } from "./query";
export function nearFilter(where: Where): false | GeoPointFilter[];
export function filter(rawResults: GeoPointRawResult[], filters: GeoPointFilter[]): GeoPointFilter;
export type GeoPointFilter = {
near: GeoPoint | ConstructorParameters<typeof GeoPoint>;
maxDistance: number;
minDistance: number;
unit: GeoDistanceUnit;
mongoKey: string;
key: string;
}
export type GeoPointRawResult = {
[key: string]: {
lat: number;
lng: number;
}
}
export class GeoPoint {
lat: number;
lng: number;
/**
*
* @example
* ```typescript
* new GeoPoint({
* lat: 145,
* lng: 96,
* });
* ```
*
* @example
* ```typescript
* new GeoPoint({
* lat: '145',
* lng: '96',
* });
* ```
*
* @param data
*/
constructor(data: {
lat: string | number,
lng: string | number,
})
/**
* @example
* ```typescript
* new GeoPoint('145,96');
* ```
*
* @example
* ```typescript
* new GeoPoint('145 , 96');
* ```
*
* @param data
*/
constructor(data: `${number},${number}`)
/**
* @example
* ```typescript
* new GeoPoint([145, 96]);
* ```
*
* @example
* ```typescript
* new GeoPoint(['145', '96']);
* ```
*
* @param data
*/
constructor(data: [string | number, string | number])
/**
* @example
* ```typescript
* new GeoPoint(145, 96);
* ```
*
* @example
* ```typescript
* new GeoPoint('145', '96');
* ```
*
* @param data
*/
constructor(lat: string | number, lng: string | number)
static distanceBetwen(
a: GeoPoint | ConstructorParameters<typeof GeoPoint>,
b: GeoPoint | ConstructorParameters<typeof GeoPoint>,
options?: GeoDistanceOptions,
): number;
distanceTo(
point: GeoPoint | ConstructorParameters<typeof GeoPoint>,
options?: GeoDistanceOptions,
): number;
toString(): `$${number},${number}`;
}
export type GeoDistanceOptions = {
type: GeoDistanceUnit;
}
export enum GeoDistanceUnit {
'kilometers',
'meters',
'miles',
'feet',
'radians',
'degrees',
}

66
types/types.d.ts vendored Normal file
View File

@ -0,0 +1,66 @@
import {DateString} from './date-string';
import {GeoPoint} from './geo';
// @achrinza: The return value is a hack to inform TypeScript of function parameter mutations.
// see: https://github.com/microsoft/TypeScript/issues/22865#issuecomment-725015710
declare function registerModelTypes(modelTypes: registerModelTypes.ModelTypes): asserts modelTypes is registerModelTypes.BuiltModelTypes;
declare namespace registerModelTypes {
// @achrinza: One of the limitations of these definitions is that the class instance
// isn't callable; Hence, changing the `value` class member must be done
// directly. This is a TypeScript limitation as class constructors cannot
// have a custom return value.
namespace Types {
function Text<T extends unknown>(value: T): T extends Text ? void : T;
class Text implements Type {
value: Text;
constructor(value: Text);
toJSON(): Text;
toObject(): Text;
}
function JSON<T extends unknown>(value: T): T extends JSON ? void : T;
class JSON implements Type {
value: unknown;
constructor(value: unknown)
toJSON(): unknown;
toObject(): unknown;
}
function Any<T extends unknown>(value: T): T extends Any ? void : T;
class Any implements Type {
value: unknown;
constructor(value: unknown);
toJSON(): unknown;
toObject(): unknown;
}
}
interface ModelTypes {
[type: string]: Type | unknown;
}
interface Type {
value: unknown;
toJSON(): unknown;
toObject(): unknown;
}
interface BuiltModelTypes extends ModelTypes {
schemaTypes: Record<string, Type> & {
'String': String;
'Number': Number;
'Date': Date
'DateString': DateString
'Binary': Buffer;
'Buffer': Buffer;
'Array': Array<unknown>;
'Object': Object;
'GeoPoint': GeoPoint
};
registerType: (type: Type, names?: string[]) => void;
}
}
export = registerModelTypes;