Skip to content

Commit

Permalink
Make includeIf infer types from the condition as well
Browse files Browse the repository at this point in the history
  • Loading branch information
reckter committed Sep 21, 2023
1 parent c7db50d commit 78d4965
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 8 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

#### 🚀 Enhancement

- Add regex validator [#17](https://github.com/opencreek/vlad/pull/17) ([@reckter](https://github.com/reckter))
- Add regex validator [#17](https://github.com/opencreek/vlad/pull/17)
([@reckter](https://github.com/reckter))

#### Authors: 1

Expand Down
1 change: 0 additions & 1 deletion polyfill/objectHasOwn.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
declare global {
interface Object {
// deno-lint-ignore ban-types
hasOwn(subject: object, property: PropertyKey): boolean;
}
}
Expand Down
10 changes: 7 additions & 3 deletions src/validators/includeIf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,16 @@ export type Condition<V1 extends Validator> =
* ```
*/

export function includeIf<V1 extends Validator>(
export function includeIf<
// deno-lint-ignore no-explicit-any
Subject extends any,
V1 extends Validator,
>(
condition:
| ((value: SubjectType<V1>, context: ContextType<V1>) => boolean)
| ((value: Subject, context: ContextType<V1>) => boolean)
| boolean,
validator1: V1,
): V1 {
): Validator<SubjectType<V1> & Subject, ReturnType<V1>> {
return function includeIfValidator(subject, context) {
const conditionResult = resolveCondition(subject, context, condition);

Expand Down
1 change: 0 additions & 1 deletion src/validators/requiredObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export function requiredObject(
message: string,
): Validator<
// we actually want all non-primitives here
// deno-lint-ignore ban-types
object,
ObjectTopLevelError<PrimitiveErrors>
>;
Expand Down
26 changes: 24 additions & 2 deletions test/validators/includeIf.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { includeIf, is, minItems } from "../../src/vlad.ts";
import {
includeIf,
is,
minItems,
object,
requiredPrimitive,
} from "../../src/vlad.ts";
import { assertEquals } from "../testingDeps.ts";

Deno.test("should not change the result of a single is validator", () => {
Expand All @@ -13,7 +19,7 @@ Deno.test("should not change the result of a single is validator", () => {

Deno.test("Should correctly include validator on condition", () => {
const validator = includeIf(
(value) => (value?.[0] ?? 0) < 5,
(value: Array<number>) => (value?.[0] ?? 0) < 5,
minItems(4, "Should have at least 5 items"),
);
const outputInvalid = validator([1]);
Expand Down Expand Up @@ -42,3 +48,19 @@ Deno.test("Should correctly include validator on static condition - false", () =

assertEquals(outputInvalid, undefined);
});

Deno.test("Should correctly infer types from the boolean condition", () => {
const validator = includeIf(
(value: { length: number }) => value.length > 5,
object({
foo: requiredPrimitive("foo is required"),
}),
);
const outputInvalid = validator({ length: 6 });
const outputValid = validator({ length: 6, foo: "bla" });
const outputValid2 = validator({ length: 2 });

assertEquals(outputInvalid, { foo: ["foo is required"] });
assertEquals(outputValid, undefined);
assertEquals(outputValid2, undefined);
});

0 comments on commit 78d4965

Please sign in to comment.