-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: API for assertion messages #1
Labels
enhancement
New feature or request
Comments
This comment has been minimized.
This comment has been minimized.
type AnyFn = (...args: any[]) => any;
interface Cata<Ok extends AnyFn, Err extends AnyFn> {
Ok: Ok,
Err: Err
}
class Ok<Value> {
constructor(private value: Value) {}
cata<
Ok extends (value: Value) => any,
Err extends AnyFn
>(x: Cata<Ok, Err>): ReturnType<Ok> {
return x.Ok(this.value);
}
}
class Err<Error> {
constructor(private error: Error) {}
cata<
Ok extends AnyFn,
Err extends (error: Error) => any
>(x: Cata<Ok, Err>): ReturnType<Err> {
return x.Err(this.error);
}
}
export class Result<Value, Error> {
static Ok<Value, Error = never>(value: Value) {
return new Result<Value, Error>(new Ok(value));
}
static Err<Error, Value = never>(error: Error) {
return new Result<Value, Error>(new Err(error));
}
constructor(private result: Ok<Value> | Err<Error>) {}
cata<
Ok extends (value: Value) => any,
Err extends (error: Error) => any
>(x: Cata<Ok, Err>): ReturnType<Ok> | ReturnType<Err> {
return (this.result.cata as AnyFn)(x);
}
map<
NextValue
>(mapper: (value: Value) => NextValue): Result<NextValue, Error> {
return this.bimap<NextValue, Error>(mapper, <T>(x: T) => x);
}
mapErr<
NextError
>(mapper: (error: Error) => NextError): Result<Value, NextError> {
return this.bimap<Value, NextError>(<T>(x: T) => x, mapper);
}
bimap<
NextValue,
NextError
>(
mapValue: (value: Value) => NextValue,
mapError: (error: Error) => NextError
): Result<NextValue, NextError> {
return new Result((this.result.cata as AnyFn)({
Ok: (value: Value) => new Ok(mapValue(value)),
Err: (error: Error) => new Err(mapError(error))
}));
}
} Here's an alternative implementation of Result |
With @trgwii's suggestions: type AnyFn = (x: never) => unknown;
interface Cata<OkFn extends AnyFn, ErrFn extends AnyFn> {
Ok: OkFn
Err: ErrFn
}
type CataOk<OkFn extends AnyFn> = Cata<OkFn, AnyFn>;
type CataErr<ErrFn extends AnyFn> = Cata<AnyFn, ErrFn>;
interface BaseResult<T, E> {
readonly ok: boolean
cata<Value, Error>(cata: Cata<(x: T) => Value, (x: E) => Error>): Value | Error
}
export namespace Result {
export class Ok<T> implements BaseResult<T, never> {
readonly ok = true as const;
constructor(readonly value: T) { }
cata<Value>(cata: CataOk<(value: T) => Value>) {
return cata.Ok(this.value);
}
}
export class Err<E> implements BaseResult<never, E> {
readonly ok = false as const;
constructor(readonly error: E) { }
cata<Error>(cata: CataErr<(error: E) => Error>) {
return cata.Err(this.error);
}
}
}
export type Result<T, E> = BaseResult<T, E> & (Result.Ok<T> | Result.Err<E>); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As we know, runtype only tells you if an type-check passed or not, and doesn't tell why it failed. This proposal outlines the new API for validation messages.
Description
Currently,
Predicate
is a function that takesx
and guards it against a type. This proposal recommends the addition of avalidate
method toPredicate
which returns the following type:Where
ValidationError
extendsError
with the propertiesexpected
andactual
describing the corresponding types as string to produce a nicer error; and by default.message
describing a generated error.Example:
Downsides:
res.ok
doesn't actually guardmsg
, and you get no static types like you normally would with the type guard.The text was updated successfully, but these errors were encountered: