docholiday

Constraints – Understanding and utilizing the TypeCheck APIs

TypeCheck is a secondary feature of the Doc-Holiday offering. It is embodied in the use of constraints when documenting sources. But there is more to the TypeCheck story.

TypeCheck is a protocol for utilizing and extending JSDoc comment syntax to declare parameters and return values with their runtime constraints as well as their types.

We begin our description of specifying constraints with a review of the support for JSDoc-style comment blocks:

Declare parameters in traditional JSDoc style:

      @param {type} name  Description

Side Note: Reversing the order of {type} and name are allowed here, but that is not canonical JSDoc style.

Also supported (and also canonical) is the use of [ ] brackets around the name to declare an optional parameter.
e.g. ` @param {string} [foobar] The foobar parameter is not required `

Descriptions may be on the same, line, or may start or continue on the lines below up until the next @param or other statement or end of comment block:

      @param {type} [name]
      The description can go here as well as on the line above, or it can continue the line above if there is one.
      The description can run multiple lines, and if JSDoc is configured for it, can support markdown syntax, as
      well as inline html.

#### Introducing Constraints

Constraints are a formatted set of expressions that may either precede or follow the description, either starting on the first line or the line below. Constraints are encapulated between < and > brackets when used in a comment block.
Zero or more constraints may be included in the comment block of a parameter or return declaration. e.g.:

      @param {number} ordinal  The ordinal value of this thing
      <Integer,Positive,NotZero>

The example declares a parameter with conventional JSDoc style, but also provides constraint keywords that will apply to this numeric type of value that specify the acceptable characteristics of that value.

Syntactically, the order of description and constraint do not matter, so this is equivalent to the above:

      @param ordinal {number}  <Integer,Positive,NotZero>
      The ordinal value of this thing

as is this:

      @param ordinal {number}  <Integer>
      The ordinal value of this thing <Positive>
      <NotZero>

The output JSDoc block will include embedded HTML to render the constraint block, as the JSDoc renderer is unaware of the role of Constraint declarations themselves. The block is assigned the CSS class “doc-constraints” should you wish to provide additional styling to this block if you are staging your own HTML pages for the documentation.

Note that all the above syntax, including constraints, also applies to the JSDoc @return (or @returns) statement, with the only difference being that the return declaration does not specify a name.

#### Multiple type constraints if there are multiple types (e.g. {string|number}) then the corresponding multiple constraint declarations may be given. example: `@param {string|number} foo <minLength=3> <Integer, min=100, max=999>

#### Constraint keywords and syntax

##### constraints for number

##### constraints for string

##### constraints for object

##### constraints for ‘array’

#### The note keyword The expression such as note=”your comment here” allows a constraint comment to be generated specifying a constraint that should be noted. example:

  @param {number} prime <integer, nonzero, note="must be a prime number">

Although no runtime checking is available for a note constraint, the note will appear as part of the constraint comment documentation.

Runtime use of TypeCheck

Doc-Holiday utilizes the TypeCheck library to parse and define constraints and render these in the documentation.

While its great to be able to declare the specification of values in the API docs, it is up to the programmer to insure that appropriate error handling is in place for incoming values that are outside of these specifications.

To help with that, the validate function is available for developers to use in their functions.

validate (value, constraint_definition_string)

Using the validate function is simple.

Import it from the doc-holiday module:

import {validate} from "@tremho/doc-holiday";

then use it in your functions to validate against the constraints specified for your values. Use the same string as the constraint declaration itself (without the < and > brackets).

/*
An example of using constraints
 */
export function typeCheckCase1(
    name:string, // <minLength=4, maxLength=32>
    age:number,  // <positive, integer, non-zero>
    phone: string, //<match=\\([0-9]{3}\\) [0-9]{3}-[0-9]{4}>
)
{
    if(!validate(name,'minLength=4, maxLength=32')) {
        throw Error('bad name')
    }
    if(!validate(age, 'positive, integer, nonzero, maxx=100')) {
        throw Error('bad age')
    }
    if(!validate(phone, 'match=\\([0-9]{3}\\) [0-9]{3}-[0-9]{4}')) {
        throw Error('bad phone')
    }
}

This crude example simply uses validate as an assertion, and throws an Error if the assertion fails. More nuanced use of validate can allow for more sophisticated error management in other scenarios.

validate will return a string. It will be an empty string (‘’) if the value passes validation, or it will contain the error message of the constraint violation that occurred.

Of course, you don’t need to use validate to check your values. As a good programmer, you’ve probably already done that, after all.

Still, you might want to run your values through validate anyway, at least during unit testing, just to make sure your functions honors the constraints as specified by your API.