aboutsummaryrefslogtreecommitdiff
path: root/src/new_fields/Types.ts
diff options
context:
space:
mode:
authorTyler Schicke <tyler_schicke@brown.edu>2019-04-19 23:13:17 -0400
committerTyler Schicke <tyler_schicke@brown.edu>2019-04-19 23:13:17 -0400
commite678ac7f21e0c44eaa8ad88577093cdb313e21bb (patch)
tree9fb0f73365ae427ebbc5c48ca1887394e16fe5bd /src/new_fields/Types.ts
parent3e96161afe4f48afa6abd1b2158b5a1c4fe85a32 (diff)
Deleted more old fields and split new stuff into multiple files
Diffstat (limited to 'src/new_fields/Types.ts')
-rw-r--r--src/new_fields/Types.ts58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
new file mode 100644
index 000000000..416298a64
--- /dev/null
+++ b/src/new_fields/Types.ts
@@ -0,0 +1,58 @@
+import { Field, Opt } from "./Doc";
+import { List } from "./List";
+
+export type ToType<T> =
+ T extends "string" ? string :
+ T extends "number" ? number :
+ T extends "boolean" ? boolean :
+ T extends ListSpec<infer U> ? List<U> :
+ T extends { new(...args: any[]): infer R } ? R : never;
+
+export type ToConstructor<T> =
+ T extends string ? "string" :
+ T extends number ? "number" :
+ T extends boolean ? "boolean" : { new(...args: any[]): T };
+
+export type ToInterface<T> = {
+ [P in keyof T]: ToType<T[P]>;
+};
+
+// type ListSpec<T extends Field[]> = { List: FieldCtor<Head<T>> | ListSpec<Tail<T>> };
+export type ListSpec<T> = { List: FieldCtor<T> };
+
+// type ListType<U extends Field[]> = { 0: List<ListType<Tail<U>>>, 1: ToType<Head<U>> }[HasTail<U> extends true ? 0 : 1];
+
+export type Head<T extends any[]> = T extends [any, ...any[]] ? T[0] : never;
+export type Tail<T extends any[]> =
+ ((...t: T) => any) extends ((_: any, ...tail: infer TT) => any) ? TT : [];
+export type HasTail<T extends any[]> = T extends ([] | [any]) ? false : true;
+
+export interface Interface {
+ [key: string]: ToConstructor<Field> | ListSpec<Field>;
+ // [key: string]: ToConstructor<Field> | ListSpec<Field[]>;
+}
+
+export type FieldCtor<T extends Field> = ToConstructor<T> | ListSpec<T>;
+
+export function Cast<T extends FieldCtor<Field>>(field: Field | null | undefined, ctor: T): ToType<T> | null | undefined {
+ if (field !== undefined && field !== null) {
+ if (typeof ctor === "string") {
+ if (typeof field === ctor) {
+ return field as ToType<T>;
+ }
+ } else if (typeof ctor === "object") {
+ if (field instanceof List) {
+ return field as ToType<T>;
+ }
+ } else if (field instanceof (ctor as any)) {
+ return field as ToType<T>;
+ }
+ } else {
+ return field;
+ }
+ return undefined;
+}
+
+export function FieldValue<T extends Field>(field: Opt<Field> | Promise<Opt<Field>>): Opt<Field> {
+ return field instanceof Promise ? undefined : field;
+}