【发布时间】:2021-08-01 11:41:39
【问题描述】:
我正在尝试使用 fp-ts 实现一些简单的数据验证,并遇到了这个codesandboxexample:
import * as E from "fp-ts/lib/Either";
import { getSemigroup, NonEmptyArray } from "fp-ts/lib/NonEmptyArray";
import { sequence } from "fp-ts/lib/Array";
import { pipe } from "fp-ts/lib/pipeable";
import { Predicate } from "fp-ts/lib/function";
type ValidationError = NonEmptyArray<string>;
type ValidationResult = E.Either<ValidationError, unknown>;
type ValidationsResult<T> = E.Either<ValidationError, T>;
interface Validator {
(x: unknown): ValidationResult;
}
interface Name extends String {}
const applicativeV = E.getValidation(getSemigroup<string>());
const validateName: (
validations: Array<Validator>,
value: unknown
) => ValidationsResult<Name> = (validations, value) =>
validations.length
? pipe(
sequence(applicativeV)(validations.map((afb) => afb(value))),
E.map(() => value as Name)
)
: E.right(value as Name);
const stringLengthPredicate: Predicate<unknown> = (v) =>
typeof v === "string" && v.length > 4;
const lengthAtLeastFour: Validator = E.fromPredicate(
stringLengthPredicate,
() => ["value must be a string of at least 5 characters"]
);
const requiredLetterPredicate: Predicate<unknown> = (v) =>
typeof v === "string" && v.includes("t");
const hasLetterT: Validator = E.fromPredicate(requiredLetterPredicate, () => [
'value must be a string that includes the letter "t"'
]);
const validations = [hasLetterT, lengthAtLeastFour];
console.log(validateName(validations, "sim"));
// {left: ['value must be a string that includes the letter "t"', 'value must be a string of at least 4 characters']}
console.log(validateName(validations, "timmy"));
// {right: 'timmy'}
Predicate 是什么?在这个例子中使用它有什么作用?我在文档中没有看到任何关于它的作用的解释,只是它是 part of the API 并且它似乎修改了提供的接口。
【问题讨论】:
-
在编程中,谓词只是一个函数,它接受一个项目并返回一个布尔值。它通常用于条件逻辑,例如过滤
arr.filter(somePredicate)。在您的情况下,它用于验证。似乎它需要一个项目,如果项目有效则返回true,否则返回false。 -
Predicate<A>是一个函数,它接受类型 A 的参数并返回一个布尔值(文档根据调用签名指定它:typescriptlang.org/docs/handbook/2/…)。它是验证框架中一个有用的构建块——谓词返回的布尔值可以解释为“参数是否有效”
标签: typescript fp-ts