Skip to content

Commit

Permalink
feat: remove useless types array
Browse files Browse the repository at this point in the history
commit 3d0dc4a97d42f8d5e003449989c87bf71e010bb3
Author: skarab42 <skarab@bluewin.ch>
Date:   Mon Apr 4 07:19:41 2022 +0200

    feat: remove useless types array
  • Loading branch information
skarab42 committed Apr 4, 2022
1 parent aaaeb71 commit f5b5a91
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 65 deletions.
46 changes: 4 additions & 42 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,3 @@
// ---------------------------------------------------------------------------
// Union to Tuple
// Taken from https://catchts.com/union-array and slightly modified
// ---------------------------------------------------------------------------
type UnionToFunction<U> = U extends unknown ? (k: U) => void : never;

type UnionToIntersection<U> = UnionToFunction<U> extends (k: infer I) => void
? I
: never;

type UnionToOverloadedFunction<U> = UnionToIntersection<UnionToFunction<U>>;

type UnionPop<U> = UnionToOverloadedFunction<U> extends (a: infer A) => void
? A
: never;

type UnionMerge<TUnion, TTuple extends unknown[]> = [TUnion, ...TTuple];

type UnionToSubArray<TUnion, TTuple extends unknown[]> = UnionToArray<
Exclude<TUnion, UnionPop<TUnion>>,
UnionMerge<UnionPop<TUnion>, TTuple>
>;

type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;

type UnionToArray<
TUnion,
TTuple extends unknown[] = [],
> = IsUnion<TUnion> extends true
? UnionToSubArray<TUnion, TTuple>
: UnionMerge<TUnion, TTuple>;

type ObjectKeys<TObject> = UnionToArray<keyof TObject>;

// ---------------------------------------------------------------------------
// Pojo Types
// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -63,9 +29,8 @@ type PojoErrorInstance<
>;

type PojoFactory<TErrorTypes extends PojoErrorTypes> = {
type: keyof TErrorTypes;
types: ObjectKeys<TErrorTypes>;
enum: Unwrap<PojoEnum<TErrorTypes>>;
type: Unwrap<PojoEnum<TErrorTypes>>;
errors: TErrorTypes;
new: <TType extends keyof TErrorTypes>(
type: TType,
...args: [...Parameters<TErrorTypes[TType]>]
Expand All @@ -74,7 +39,6 @@ type PojoFactory<TErrorTypes extends PojoErrorTypes> = {
type: TType,
error: unknown,
) => error is PojoErrorInstance<TErrorTypes, TType>;
errors: TErrorTypes;
};

// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -131,7 +95,7 @@ function fakeEnum<TErrorTypes extends PojoErrorTypes>(
export function factory<TErrorTypes extends PojoErrorTypes>(
errors: TErrorTypes,
): Unwrap<PojoFactory<TErrorTypes>> {
const { enumKeys, enumObject } = fakeEnum(errors);
const { enumObject } = fakeEnum(errors);

function newFactory<TType extends keyof TErrorTypes>(
type: TType,
Expand All @@ -151,9 +115,7 @@ export function factory<TErrorTypes extends PojoErrorTypes>(
}

return {
type: enumKeys as unknown as typeof enumKeys[number],
types: enumKeys as ObjectKeys<TErrorTypes>,
enum: enumObject as Unwrap<typeof enumObject>,
type: enumObject as Unwrap<typeof enumObject>,
new: newFactory,
is: isFactory,
errors,
Expand Down
35 changes: 12 additions & 23 deletions test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { factory, PojoError } from "../src";
import { expect, test } from "vitest";
import {
ErrorsUnion,
errors,
ErrorsArray,
ErrorsEnum,
errorsArray,
errorsEnum,
} from "./fixtures";
import { factory, PojoError } from "../src";
import { errors, ErrorsEnum, errorsEnum } from "./fixtures";

function assertType<TExpected>(input: TExpected): TExpected {
return input;
Expand All @@ -16,35 +9,31 @@ function assertType<TExpected>(input: TExpected): TExpected {
test("factory", () => {
const myErrors = factory(errors);

assertType<ErrorsUnion>(myErrors.type);
assertType<ErrorsArray>(myErrors.types);
assertType<ErrorsEnum>(myErrors.enum);
assertType<ErrorsEnum>(myErrors.type);
assertType<typeof errors>(myErrors.errors);

expect(myErrors.type).toEqual(errorsArray);
expect(myErrors.types).toEqual(errorsArray);
expect(myErrors.enum).toEqual(errorsEnum);
expect(myErrors.type).toEqual(errorsEnum);
expect(myErrors.errors).toBe(errors);
});

test("factory.new", () => {
const myErrors = factory(errors);

myErrors.new("FATAL", "Oupsy!");
myErrors.new(myErrors.enum.FATAL);
myErrors.new(myErrors.type.FATAL);

// @ts-expect-error Expected 2-3 arguments, but got 1.
myErrors.new(myErrors.enum.PAGE_NOT_FOUND);
myErrors.new(myErrors.type.PAGE_NOT_FOUND);
// @ts-expect-error Expected 1-2 arguments, but got 3.
myErrors.new(myErrors.enum.FATAL, "Oupsy!", 42);
myErrors.new(myErrors.type.FATAL, "Oupsy!", 42);

// @ts-expect-error Argument of type '"PROUT"' is not assignable ...
expect(() => myErrors.new("PROUT")).toThrow();
});

test("error without parameter", () => {
const myErrors = factory(errors);
const myError = myErrors.new(myErrors.enum.FATAL);
const myError = myErrors.new(myErrors.type.FATAL);

assertType<"FATAL">(myError.type);
assertType<Parameters<typeof errors.FATAL>>(myError.args);
Expand All @@ -70,7 +59,7 @@ test("error without parameter", () => {

test("error with one parameter", () => {
const myErrors = factory(errors);
const myError = myErrors.new(myErrors.enum.FATAL, "My custom fatal error");
const myError = myErrors.new(myErrors.type.FATAL, "My custom fatal error");

try {
throw myError;
Expand All @@ -89,7 +78,7 @@ test("error with one parameter", () => {
test("error with two parameter (url, undefined)", () => {
const myErrors = factory(errors);
const myError = myErrors.new(
myErrors.enum.PAGE_NOT_FOUND,
myErrors.type.PAGE_NOT_FOUND,
"http://www.skarab42.dev",
);

Expand Down Expand Up @@ -119,7 +108,7 @@ test("error with two parameters (url, user)", () => {
const user = { name: "skarab42", isAdmin: true };
const myErrors = factory(errors);
const myError = myErrors.new(
myErrors.enum.PAGE_NOT_FOUND,
myErrors.type.PAGE_NOT_FOUND,
"http://www.skarab42.dev",
user,
);
Expand Down Expand Up @@ -153,7 +142,7 @@ test("error to object/json", () => {
const user = { name: "skarab42", isAdmin: true };
const myErrors = factory(errors);
const myError = myErrors.new(
myErrors.enum.PAGE_NOT_FOUND,
myErrors.type.PAGE_NOT_FOUND,
"http://www.skarab42.dev",
user,
);
Expand Down

0 comments on commit f5b5a91

Please sign in to comment.