sanctuary-type-identifiers
A type is a set of values. Boolean, for example, is the type comprising true
and false
. A value may be a member of multiple types (42
is a member of Number, PositiveNumber, Integer, and many other types).
In certain situations it is useful to divide JavaScript values into non-overlapping types. The language provides two constructs for this purpose: the typeof
operator and Object.prototype.toString
. Each has pros and cons, but neither supports user-defined types.
sanctuary-type-identifiers comprises:
- an npm and browser -compatible package for deriving the type identifier of a JavaScript value; and
- a specification which authors may follow to specify type identifiers for their types.
Specification
For a type to be compatible with the algorithm:
-
every member of the type MUST have a
@@type
property (the type identifier); and -
the type identifier MUST be a string primitive and SHOULD have format
'<namespace>/<name>[@<version>]'
, where:-
<namespace>
MUST consist of one or more characters, and SHOULD equal the name of the npm package which defines the type (including scope where appropriate); -
<name>
MUST consist of one or more characters, and SHOULD be the unique name of the type; and -
<version>
MUST consist of one or more digits, and SHOULD represent the version of the type.
-
If the type identifier does not conform to the format specified above, it is assumed that the entire string represents the name of the type; namespace will be null
and version will be 0
.
If the version is not given, it is assumed to be 0
.
Usage
const type = require ('sanctuary-type-identifiers');
> const Identity$prototype = {
. '@@type': 'my-package/Identity@1',
. '@@show': function() {
. return 'Identity (' + show (this.value) + ')';
. }
. }
> const Identity = value =>
. Object.assign (Object.create (Identity$prototype), {value})
> type (Identity (0))
'my-package/Identity@1'
> type.parse (type (Identity (0)))
{namespace: 'my-package', name: 'Identity', version: 1}
API
type :: Any -> String
Takes any value and returns a string which identifies its type. If the value conforms to the specification, the custom type identifier is returned.
> type (null)
'Null'
> type (true)
'Boolean'
> type (Identity (0))
'my-package/Identity@1'
type.parse :: String -> { namespace :: Nullable String, name :: String, version :: Number }
Takes any string and parses it according to the specification, returning an object with namespace
, name
, and version
fields.
> type.parse ('my-package/List@2')
{namespace: 'my-package', name: 'List', version: 2}
> type.parse ('nonsense!')
{namespace: null, name: 'nonsense!', version: 0}
> type.parse (type (Identity (0)))
{namespace: 'my-package', name: 'Identity', version: 1}