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
@@typeproperty (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}