datum-focus
Version:
Data shape, model, metadata, JSON, JSON Schema, GraphQL, MongoDB query and aggregations, iterator generators
51 lines (46 loc) • 1.55 kB
text/typescript
import { ARRAY } from "../../array";
import { BooleanType } from "../../boolean";
import { DateType } from "../../date";
import { IntegerType, NumberType } from "../../number";
import { DICTIONARY, KnownRecord, RECORD, RecordType } from "../../record";
import { StringType } from "../../string";
export type PrimitiveNameOf<T> = T extends Boolean
? BooleanType
: T extends Date
? DateType
: T extends BigInt
? IntegerType
: T extends Number
? NumberType
: T extends String
? StringType
: RecordType;
type FieldsOf<T> = typeof RECORD | [string, typeof RECORD] | FieldMap<T>;
type ArrayOf<U> = U extends KnownRecord
?
| [FieldMap<U> | typeof RECORD, typeof ARRAY]
| [string, typeof RECORD, typeof ARRAY]
: [PrimitiveNameOf<U>, typeof ARRAY];
type DictionaryOf<V> = V extends KnownRecord
?
| typeof RECORD
| [string, typeof RECORD, typeof DICTIONARY, StringType?]
| [typeof RECORD, typeof DICTIONARY, StringType?]
| [FieldMap<V>, typeof DICTIONARY, StringType?] // [model name, , , key type]
: [PrimitiveNameOf<V>, typeof DICTIONARY, StringType?]; // [type, , key type]
export type TypeOf<T> = T extends Array<infer U>
? ArrayOf<U>
: T extends Record<string, infer V>
? DictionaryOf<V> // [type, , key type]
: T extends KnownRecord
? FieldsOf<T>
: PrimitiveNameOf<T>;
export interface FieldModel<T> {
default?: T;
name: string;
type: TypeOf<T>;
}
export type FieldDescriptor<T> = Omit<FieldModel<T>, "name">;
export type FieldMap<T extends {}> = {
[P in keyof T]: FieldDescriptor<T[P]>;
};