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
{
"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"
}
}
}
}
}
}
}
Calling 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"
}