Coder Social home page Coder Social logo

codefeathers / runtype Goto Github PK

View Code? Open in Web Editor NEW
4.0 3.0 0.0 417 KB

Runtime type assertions that return

Home Page: https://codefeathers.github.io/runtype

JavaScript 0.93% TypeScript 99.07%
runtime type assertion typescript type-guards runtype assertions

runtype's People

Contributors

mkrhere avatar uditkarode avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

runtype's Issues

Proposal: `struct.extend` and `struct.exact`

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.

Example

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.

Problem

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.

Example

Existing:

const Message = struct({ from: string, to: string, content: string });

// .. elsewhere

const ForwardedMessage = extend(Message, { isForward: true });

Proposed:

const ForwardedMessage = Message.extend({ isForward: bool });

Unaddressed issues

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 exacted. 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.

Proposal: API for assertion messages

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 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.

Example:

const Message = struct({ from: string, to: string, content: string });

// elsewhere
const res = Message.validate(msg);

if (res.ok) {
  // use msg
} else {
  // res.error
}

Downsides:

  • res.ok doesn't actually guard msg, and you get no static types like you normally would with the type guard.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.