Skip to content

Commit

Permalink
Merge pull request #19 from opencreek/fix-some-type
Browse files Browse the repository at this point in the history
Fix `some` types
  • Loading branch information
reckter authored Oct 17, 2023
2 parents 23c8fa9 + 5dae18e commit fbc6422
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 17 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

#### 🚀 Enhancement

- Make includeIf infer types from the condition as well [#18](https://github.com/opencreek/vlad/pull/18) ([@reckter](https://github.com/reckter))
- Make includeIf infer types from the condition as well
[#18](https://github.com/opencreek/vlad/pull/18)
([@reckter](https://github.com/reckter))

#### Authors: 1

Expand Down
7 changes: 2 additions & 5 deletions src/validators/all.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// @ts-nocheck Deepmerge magic, will be replaced

import { PrimitiveErrors, SubjectType, Validator } from "../types.ts";
import { SubjectType, Validator } from "../types.ts";
import { deepMerge } from "../deps.ts";

type PartialReturnOrPrimitive<V extends Validator> = ReturnType<V> extends
PrimitiveErrors | undefined ? NonNullable<ReturnType<V>>
: Partial<ReturnType<V>>;
import { PartialReturnOrPrimitive } from "./partialReturnOrPrimitive.ts";

/**
* Builds a validator function that applies all given validators to a value, merging their results
Expand Down
5 changes: 5 additions & 0 deletions src/validators/partialReturnOrPrimitive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { PrimitiveErrors, Validator } from "../types.ts";

export type PartialReturnOrPrimitive<V extends Validator> =
ReturnType<V> extends PrimitiveErrors | undefined ? NonNullable<ReturnType<V>>
: Partial<ReturnType<V>>;
21 changes: 11 additions & 10 deletions src/validators/some.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { SubjectType, Validator } from "../types.ts";
import { deepMerge } from "../deps.ts";
import { PartialReturnOrPrimitive } from "./partialReturnOrPrimitive.ts";

/**
* Builds a validator function that validates, if at least one of the given validators passes
Expand All @@ -21,25 +22,25 @@ import { deepMerge } from "../deps.ts";
* ```
*/
// deno-fmt-ignore
export function some<V1 extends Validator>(validator1: V1): Validator<Partial<SubjectType<V1>>, Partial<ReturnType<V1>>>
export function some<V1 extends Validator>(validator1: V1): Validator<Partial<SubjectType<V1>>, PartialReturnOrPrimitive<V1>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator>(validator1: V1, validator2: V2): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>>>
export function some<V1 extends Validator, V2 extends Validator>(validator1: V1, validator2: V2): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator>(validator1: V1, validator2: V2, validator3: V3): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>> & Partial<ReturnType<V3>>>
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator>(validator1: V1, validator2: V2, validator3: V3): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2> & PartialReturnOrPrimitive<V3>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>> & Partial<ReturnType<V3>> & Partial<ReturnType<V4>>>
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2> & PartialReturnOrPrimitive<V3> & PartialReturnOrPrimitive<V4>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>> & Partial<ReturnType<V3>> & Partial<ReturnType<V4>> & Partial<ReturnType<V5>>>
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2> & PartialReturnOrPrimitive<V3> & PartialReturnOrPrimitive<V4> & PartialReturnOrPrimitive<V5>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>> & Partial<ReturnType<V3>> & Partial<ReturnType<V4>> & Partial<ReturnType<V5>> & Partial<ReturnType<V6>>>
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2> & PartialReturnOrPrimitive<V3> & PartialReturnOrPrimitive<V4> & PartialReturnOrPrimitive<V5> & PartialReturnOrPrimitive<V6>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator, V7 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6, validator7: V7): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>> & Partial<SubjectType<V7>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>> & Partial<ReturnType<V3>> & Partial<ReturnType<V4>> & Partial<ReturnType<V5>> & Partial<ReturnType<V6>> & Partial<ReturnType<V7>>>
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator, V7 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6, validator7: V7): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>> & Partial<SubjectType<V7>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2> & PartialReturnOrPrimitive<V3> & PartialReturnOrPrimitive<V4> & PartialReturnOrPrimitive<V5> & PartialReturnOrPrimitive<V6> & PartialReturnOrPrimitive<V7>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator, V7 extends Validator, V8 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6, validator7: V7, validator8: V8): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>> & Partial<SubjectType<V7>> & Partial<SubjectType<V8>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>> & Partial<ReturnType<V3>> & Partial<ReturnType<V4>> & Partial<ReturnType<V5>> & Partial<ReturnType<V6>> & Partial<ReturnType<V7>> & Partial<ReturnType<V8>>>
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator, V7 extends Validator, V8 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6, validator7: V7, validator8: V8): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>> & Partial<SubjectType<V7>> & Partial<SubjectType<V8>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2> & PartialReturnOrPrimitive<V3> & PartialReturnOrPrimitive<V4> & PartialReturnOrPrimitive<V5> & PartialReturnOrPrimitive<V6> & PartialReturnOrPrimitive<V7> & PartialReturnOrPrimitive<V8>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator, V7 extends Validator, V8 extends Validator, V9 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6, validator7: V7, validator8: V8, validator9: V9): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>> & Partial<SubjectType<V7>> & Partial<SubjectType<V8>> & Partial<SubjectType<V9>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>> & Partial<ReturnType<V3>> & Partial<ReturnType<V4>> & Partial<ReturnType<V5>> & Partial<ReturnType<V6>> & Partial<ReturnType<V7>> & Partial<ReturnType<V8>> & Partial<ReturnType<V9>>>
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator, V7 extends Validator, V8 extends Validator, V9 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6, validator7: V7, validator8: V8, validator9: V9): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>> & Partial<SubjectType<V7>> & Partial<SubjectType<V8>> & Partial<SubjectType<V9>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2> & PartialReturnOrPrimitive<V3> & PartialReturnOrPrimitive<V4> & PartialReturnOrPrimitive<V5> & PartialReturnOrPrimitive<V6> & PartialReturnOrPrimitive<V7> & PartialReturnOrPrimitive<V8> & PartialReturnOrPrimitive<V9>>
// deno-fmt-ignore
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator, V7 extends Validator, V8 extends Validator, V9 extends Validator, V10 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6, validator7: V7, validator8: V8, validator9: V9, validator10: V10): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>> & Partial<SubjectType<V7>> & Partial<SubjectType<V8>> & Partial<SubjectType<V9>> & Partial<SubjectType<V10>>, Partial<ReturnType<V1>> & Partial<ReturnType<V2>> & Partial<ReturnType<V3>> & Partial<ReturnType<V4>> & Partial<ReturnType<V5>> & Partial<ReturnType<V6>> & Partial<ReturnType<V7>> & Partial<ReturnType<V8>> & Partial<ReturnType<V9>> & Partial<ReturnType<V10>>>
export function some<V1 extends Validator, V2 extends Validator, V3 extends Validator, V4 extends Validator, V5 extends Validator, V6 extends Validator, V7 extends Validator, V8 extends Validator, V9 extends Validator, V10 extends Validator>(validator1: V1, validator2: V2, validator3: V3, validator4: V4, validator5: V5, validator6: V6, validator7: V7, validator8: V8, validator9: V9, validator10: V10): Validator<Partial<SubjectType<V1>> & Partial<SubjectType<V2>> & Partial<SubjectType<V3>> & Partial<SubjectType<V4>> & Partial<SubjectType<V5>> & Partial<SubjectType<V6>> & Partial<SubjectType<V7>> & Partial<SubjectType<V8>> & Partial<SubjectType<V9>> & Partial<SubjectType<V10>>, PartialReturnOrPrimitive<V1> & PartialReturnOrPrimitive<V2> & PartialReturnOrPrimitive<V3> & PartialReturnOrPrimitive<V4> & PartialReturnOrPrimitive<V5> & PartialReturnOrPrimitive<V6> & PartialReturnOrPrimitive<V7> & PartialReturnOrPrimitive<V8> & PartialReturnOrPrimitive<V9> & PartialReturnOrPrimitive<V10>>

export function some(...validators) {
if (validators.length === 0) {
Expand Down
1 change: 1 addition & 0 deletions src/vlad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from "./validators/includeIf.ts";
export * from "./validators/regex.ts";

export * from "./types.ts";
export { type PartialReturnOrPrimitive } from "./validators/partialReturnOrPrimitive.ts";
18 changes: 17 additions & 1 deletion test/validators/some.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { some } from "../../src/validators/some.ts";
import { is, maxItems, minItems } from "../../src/vlad.ts";
import {
is,
maxItems,
minItems,
PrimitiveErrors,
Validator,
} from "../../src/vlad.ts";
import { assertEquals } from "../testingDeps.ts";

Deno.test("should not change the result of a single is validator", () => {
Expand Down Expand Up @@ -52,3 +58,13 @@ Deno.test("should correctly merge primitive errors", () => {
_self: ["Must have at least 3 items", "Must have at least 2 items"],
});
});

Deno.test("should correctly infer types with primitive validators", () => {
const validator = some(
is(3, "must be 3"),
is(2, "must be 2"),
) satisfies Validator<Partial<number>, PrimitiveErrors>;
const output = validator(1);

assertEquals(output, ["must be 3", "must be 2"]);
});

0 comments on commit fbc6422

Please sign in to comment.