Skip to content

Commit

Permalink
fix: add union type
Browse files Browse the repository at this point in the history
  • Loading branch information
izatop committed Nov 8, 2020
1 parent e823e24 commit 549ea97
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 4 deletions.
6 changes: 3 additions & 3 deletions packages/input/src/Type/ObjectType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import {TypeAbstract} from "../TypeAbstract";

export class ObjectType<TValue extends Record<string, any>> extends TypeAbstract<TValue, Record<string, any>> {
readonly #fields: ObjectFields<TValue>;
readonly #name?: string;
readonly #name: string;

constructor(fields: ObjectFields<TValue>, name?: string) {
constructor(fields: ObjectFields<TValue>, name = "Object") {
super();
this.#fields = fields;
this.#name = name;
}

public get name(): string {
return this.#name ?? super.name;
return this.#name;
}

public async validate(payload: MayNullable<Record<string, any>>): Promise<TValue> {
Expand Down
27 changes: 27 additions & 0 deletions packages/input/src/Type/Union.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {MayNullable, Promisify} from "@typesafeunit/util";
import {MayInput} from "../interfaces";
import {TypeAbstract} from "../TypeAbstract";

export type UnionSelector<TInput extends MayInput> =
(input: MayNullable<TInput>) => TypeAbstract<unknown> | undefined;

export class Union<TValue, TInput extends MayInput = MayInput> extends TypeAbstract<TValue, TInput> {
readonly #selector: UnionSelector<TInput>;
readonly #name: string;

constructor(selector: UnionSelector<TInput>, name = "Union") {
super();
this.#selector = selector;
this.#name = name;
}

public get name(): string {
return this.#name;
}

public validate(input: MayNullable<TInput>): Promisify<TValue> {
const type = this.#selector(input);
this.assert(!!type, `${this.name} detection was failed`, input);
return type.validate(input) as Promisify<TValue>;
}
}
1 change: 1 addition & 0 deletions packages/input/src/Type/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export * from "./NonNull";
export * from "./ObjectType";
export * from "./Text";
export * from "./Varchar";
export * from "./Union";
export * from "./Bool";
31 changes: 30 additions & 1 deletion packages/input/test/src/Main.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
import {DateTime} from "@typesafeunit/input";
import {isInstanceOf} from "@typesafeunit/util";
import {Bool, Float, Int, List, NonNull, Nullable, ObjectType, Text, TypeAbstract, validate, Varchar} from "../../src";
import {
Bool,
Float,
Int,
List,
NonNull,
Nullable,
ObjectType,
Text,
TypeAbstract,
Union,
validate,
Varchar,
} from "../../src";
import {AssertionObjectError} from "../../src/Assertion";
import {ITestType} from "./interfaces";

describe("Test Input", () => {
const rand = Math.random();
const union = new Union<Date | boolean, string | number | boolean>(
(input) => {
switch (typeof input) {
case "string":
case "number":
return DateTime;
case "boolean":
return Bool;
}
},
);

const samples: [any, any, TypeAbstract<any, any>][] = [
[1, 1, Int],
[false, false, Bool],
Expand All @@ -18,6 +44,9 @@ describe("Test Input", () => {
["text", "text", new Varchar({min: 0, max: 4})],
[{v: 1, b: true, n: []}, {v: 1, b: true}, new ObjectType({v: Int, b: Bool})],
[[1, 2, 3], [1, 2, 3], new List(Int)],
[false, false, union],
["2020-01-01", new Date("2020-01-01"), union],
[new Date("2020-01-01").getTime(), new Date("2020-01-01"), union],
];

test.each(samples)(
Expand Down

0 comments on commit 549ea97

Please sign in to comment.