TypeInfo
Note: This has only been testet server-side with Deno V8
This package provides Extended Type Detection for an instantiated javascript object. The getTypes()
function traverses a single- or multi-level user defined object and returns another object showing the inferred types. The detected javascript data types are:
- symbol
- string
- number
- bigint
- Date
- boolean
- Regexp
- object
- Array, including typed arrays like
Int16Array
- function
- null
- undefined
as well as:
- User defined classes
You should Note:
- This implementation uses
Object.getPrototypeOf(obj).constructor.name
when dealing with classes, a field that has not always been present in the past, as well as the V8 parameterObject.getOwnPropertyDescriptor(obj, 'name').value
, which used to be calledstoreName
and thus may as well be subject to change in the future. - Since the data type lookup is done on an instantiated javascript object you will have to initialize the object with values that allow for detection of the type - 'null' and 'undefined' are by definition not very telling. In the same vain, it is not possible to assign multiple types to an object key.
- Some types like 'enum' in the TypeScript example below, as well all other non-primitive TypeScript types, are not detectable once compiled to javascript, and only the assigned value type can be found.
- User defined classes are detected.
Given an instantiated object (the complete file can be found in the './examples' directory):
import { getTypes } from "../mod.ts"
(...)
const employee = {
recId: Symbol('REC-ID'),
employeeNumber: BigInt(9007199254740991),
lastName: "Hope",
firstName: "Bob",
extension: "A",
email: "bob.hope@heaven.com",
officeCode: undefined,
reportsTo: null,
jobTitle: "BS Manager",
hired: new Date(2018, 11, 24, 10, 33, 30, 0),
active: true,
regexp: /^.*XXX.*$/,
tools: ['pen', 10, Symbol('ARR-ID')],
scoreText: DirectionText.Up,
image: new Image('Office'),
image2: new Image2('Cubicle'),
images: [ new Image('Table'), new Image2('Computer') ]
}
const dataTypes = getTypes('Employee', employee)
console.log(JSON.stringify(dataTypes, undefined, 2))
The call format is getTypes('Employee', employee, false)
and the arguments are:
- name: Your name for the type object
- obj: The object to infer types from
- flatten: if set to
true
the returned object will be flattened (the default is 'false').
Try running the example:
deno run ./examples/typeInfo.ts
produces the following output, where you should note:
- The resulting object will have the same nesting as the original.
- Even though the enum type is not detected, the correct type of the value assigned is found
- For an Array with multiple types are assigned, these types are correctly listed
- User defined classes are listed
Calling{ "name": "Employee", "type": "object", "props": { "recId": { "desc": "Rec Id", "type": "symbol" }, "employeeNumber": { "desc": "Employee Number", "type": "bigint" }, "lastName": { "desc": "Last Name", "type": "string" }, "firstName": { "desc": "First Name", "type": "string" }, "extension": { "type": "string" }, "email": { "type": "string" }, "officeCode": { "desc": "Office Code", "type": "undefined" }, "reportsTo": { "desc": "Reports To", "type": "null" }, "jobTitle": { "desc": "Job Title", "type": "string" }, "hired": { "type": "Date", "props": {} }, "active": { "type": "boolean" }, "regexp": { "type": "RegExp", "props": {} }, "tools": { "type": "Array", "props": { "0": { "type": "string" }, "1": { "type": "number" }, "2": { "type": "symbol" } } }, "scoreText": { "desc": "Score Text", "type": "string" }, "image": { "type": "Image", "props": { "name": { "type": "string" }, "format": { "type": "string" } } }, "image2": { "desc": "Image 2", "type": "Image2", "props": { "name": { "type": "string" }, "format": { "type": "string" }, "score": { "type": "number" } } }, "images": { "type": "Array", "props": { "0": { "type": "Image", "props": { "name": { "type": "string" }, "format": { "type": "string" } } }, "1": { "type": "Image2", "props": { "name": { "type": "string" }, "format": { "type": "string" }, "score": { "type": "number" } } } } } } }
getTypes('Employee', employee, true)
will return:{ "name": "Employee", "type": "object", "props.recId.desc": "Rec Id", "props.recId.type": "symbol", "props.employeeNumber.desc": "Employee Number", "props.employeeNumber.type": "bigint", "props.lastName.desc": "Last Name", "props.lastName.type": "string", "props.firstName.desc": "First Name", "props.firstName.type": "string", "props.extension.type": "string", "props.email.type": "string", "props.officeCode.desc": "Office Code", "props.officeCode.type": "undefined", "props.reportsTo.desc": "Reports To", "props.reportsTo.type": "null", "props.jobTitle.desc": "Job Title", "props.jobTitle.type": "string", "props.hired.type": "Date", "props.hired.props": {}, "props.active.type": "boolean", "props.regexp.type": "RegExp", "props.regexp.props": {}, "props.tools.type": "Array", "props.tools.props.0.type": "string", "props.tools.props.1.type": "number", "props.tools.props.2.type": "symbol", "props.scoreText.desc": "Score Text", "props.scoreText.type": "string", "props.image.type": "Image", "props.image.props.name.type": "string", "props.image.props.format.type": "string", "props.image2.desc": "Image 2", "props.image2.type": "Image2", "props.image2.props.name.type": "string", "props.image2.props.format.type": "string", "props.image2.props.score.type": "number", "props.images.type": "Array", "props.images.props.0.type": "Image", "props.images.props.0.props.name.type": "string", "props.images.props.0.props.format.type": "string", "props.images.props.1.type": "Image2", "props.images.props.1.props.name.type": "string", "props.images.props.1.props.format.type": "string", "props.images.props.1.props.score.type": "number" }