Giter Club home page Giter Club logo

black-tie's Introduction

black-tie

A formal approach to semantic validation

What is this?

black-tie is a simple, decorator based approach for semantic validation of TypeScript classes. Black-tie uses the Object Constraint Language to perform these validations.

Invariants

Suppose we have a class that looks like this:

class MediaItem {
    name: string;
    mediaType: 'book' | 'movie';
    isbn: string;
}

We want to enforce the rule that any book should have an ISBN number.

@ContextFor(`inv bookHasIsbn: self.mediaType = "book" implies not self.isbn.oclIsUndefined()`)
class MediaItem {
    name: string;
    mediaType: 'book' | 'movie';
    isbn: string;
}

const myFavoriteBook: MediaItem = {
    name: "Adventures of Huckleberry Finn",
    mediaType: "book",
    isbn: "9781101628270"
}

const errors = await validator.validate(myFavoriteBook);
// no errors will be returned

Validating nested objects

If your object contains nested objects and you want the validator to perform their validation too, then you need to use the @ValidateNested() decorator:

export class Post {
    @ValidateNested()
    user: User;
}

Roadmap

  • Support for preconditions and postconditions.
  • Integration with class-validator.

black-tie's People

Contributors

jdziurlaj avatar

Stargazers

Vedanta-krit das (Alex Vedmedenko) avatar  avatar

Watchers

Jared avatar James Cloos avatar  avatar

black-tie's Issues

Native Post and Preconditionals

We could do OCL based Post and Preconditionals, but let's see how hard it would be to do native preconditionals.

OCL conditionals operate with contextual access to a method's arguments, result, and for postconditional, values of the arguments prior to execution, pre@.

To replicate this using TypeScript decorators, we would need the same access to the arguments as OCL does. This can be (poorly) replicated using a custom generic type that extracts the arguments of a function as a tuple list.

type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;

We can then define a decorator function like so...

export function Preconditional<TArgs>(expr: (args: TArgs) => boolean) {...}

We can then define a Preconditional on a method

export class Student {
    @Preconditional<ArgumentTypes<typeof Student.addCourse>>((args) => args[0] > 0)   
    public static addCourse(courseId: number) {...}
}

The above example works for Preconditions on the arguments, but what about the larger environment? Postconditionals are often used to validate not only the return value, but side effects that the function generated, such as a change to an instance field.

Some notes:

  1. The decorator invocation is ugly, very ugly.
  2. The ArgumentTypes gives us a tuple with argument positions and types, not the argument names. More ugly.

TypeScript changes to support generic decorators.

The above sections prove that preconditions and postconditionals can be implemented without changes. However, the required boilerplate is highly verbose and prone to error. A solution would be for the typescript language service to pass two generic parameters whenever it sees a generic function. This would bake in this functionality. But perhaps we could be more cautious, and just define this as the target type of the decorator. This would result in much simpler definitions, such as

@Preconditional<ArgumentTypes<this>>((args) => args[0].courseNumber > 5)

So in the above example, this would be logically equivalent to typeof Student.addCourse

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.