codefeathers / runtype Goto Github PK
View Code? Open in Web Editor NEWRuntime type assertions that return
Home Page: https://codefeathers.github.io/runtype
Runtime type assertions that return
Home Page: https://codefeathers.github.io/runtype
This proposal is two-part because the use of extend
ties in with the use of exact
. We will see why below.
*1) struct.exact
At the moment, struct
only validates loose objects; when there are more props than required, they're simply ignored. This is probably safe for most use-cases, but some times you might want a strict mode where additional props are disallowed.
The proposed API for this is: struct(S).exact(x) -> x is exact S
There will be no change in the type guard. At compile time, exact
is similar to loose validation, because any x
will always be accepted as input, and it's unsafe to use un-validated props either way. It's only a runtime change where exact
fails if there were more props than expected.
const Message = struct({ from: string, to: string, content: string });
const x = { from, to, content };
if (Message.exact(x)) {
// x is valid
}
const y = { from, to, content, isForward };
if (Message.exact(y)) {
// y is not valid Message, since it has an unexpected prop `isForward`
}
*2) struct.extend
Currently, extend
is its own Higher Order Predicate. Its behaviour is such that it accepts a struct predicate as first param, and a struct as second param. The definition of the first struct is enforced at compile-time; you cannot extend from an arbitrary type (use and
for that). x
must satisfy both structs, while the second struct may not contradict the first; only extend it.
Because struct.exact
as defined previously is also a predicate, extend
will have to disallow exact structs as a parameter, because its runtime validation will fail before being extensible.
Because extend
is very tied in to struct
, moving it to a method makes extend
and exact
mutually exclusive. I'd also expect extend
to be used as an extension of a previously defined struct, rather than inline definition like extend(struct(...), ...)
. Making it a method makes a lot of sense.
Existing:
const Message = struct({ from: string, to: string, content: string });
// .. elsewhere
const ForwardedMessage = extend(Message, { isForward: true });
Proposed:
const ForwardedMessage = Message.extend({ isForward: bool });
There are still some concerns to be worried about, namely deeply strict structs, like this one:
const MessageContent = struct({
type: oneOf("html", "markdown"),
value: string
}).exact; // notice that MessageContent has been exact-ed
const Message = struct({
from: string,
to: string,
content: MessageContent,
});
Say Message
is extended like so:
const MessageWithAttachment = Message.extend({
content: {
attachment: string,
},
});
This check fails to behave as expected at runtime because MessageWithAttachment
will always fail as the original struct's content
is exact
ed. This could be solved by having a way to extract the non-exact predicate out of an exact predicate, but we're yet to decide whether implicitly un-exacting structs when extending them is the right way to go.
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.
Currently, Predicate
is a function that takes x
and guards it against a type. This proposal recommends the addition of a validate
method to Predicate
which returns the following type:
{ ok: true, value: T } | { ok: false, error: ValidationError }
Where ValidationError
extends Error
with the properties expected
and actual
describing the corresponding types as string to produce a nicer error; and by default .message
describing a generated error.
const Message = struct({ from: string, to: string, content: string });
// elsewhere
const res = Message.validate(msg);
if (res.ok) {
// use msg
} else {
// res.error
}
res.ok
doesn't actually guard msg
, and you get no static types like you normally would with the type guard.A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.