An importable TypeScript / JavaScript method to fix the JavaScript typeof operator. This code is written as a module for the deno runtime. If you are using JavaScript with node.js there is also an included type_of.mjs file you can download. If you would like to visit the deno.land module page for type_of() type_of deno module.
- General Info
- Features
- Tech
- Screenshots
- Setup
- Usage
- Examples
- Versions
- Acknowledgements
- Contact
- License
While programming many years with JavaScript, I've ran into many bugs using the typeof operator to check data types. The bugs have carried over to using TypeScript as well. I decided to research all the bugs and build an alternative typeof as a method named type_of (). This module is created to work on the deno runtime.
Below are the current features of the type_of () module.
- Proper undefined check
- Proper null check
- Can type check all common JavaScript primitive types.
- Can type check complex types like object and seperate it into exact types.
- Can type check all methods including anonymous arrow functions.
- Can type check arrays.
- Using extended option can return class names.
- Can type check new JavaScript types like bigint and symbol.
- Can type check internal JavaScript functions like eval, JSON, NaN, etc.
- JavaScript Errors can return proper type and name.
- In extended mode can seperate numbers into number types, integer, float, nan, infinity, bigint.
- In extended mode can seperate strings into 'string' for literal, and 'string Object' for new String('foo');
- Deno - version 1.25.0
- TypeScript - version 4.7.4
- V8 - version 10.4.132.20
- Visual Studio Code - 1.70+
Things you will need to get this module running. You will need to install Deno runtime for Javascript / TypeScript.
# git clone [email protected]:Codevendor/type_of.git
Installing code from deno.land with import statement. type_of deno module
The deno url can be changed to whatever version you would like to use https://deno.land/x/type_of@v*.*.*/mod.ts. Just change (*) to the version number. i.e: 2.1.0
// Snake case version - type_of();
import { type_of } from "https://deno.land/x/[email protected]/mod.ts";
// Or
// Camel case alias - typeOf()
import { typeOf } from "https://deno.land/x/[email protected]/mod.ts";
The method type_of () was built to mimic the JavaScript typeof operator. The purpose is to keep the familiarity of the functionality while correcting the known bugs with the operator code. I have also extended the method with a second optional boolean parameter for returning names of functions, classes, errors, etc.
Listed below are the method signature(s).
Method Signature |
---|
type_of ( src: unknown ) |
type_of ( src: unknown, extended: boolean = false ) |
alias typeOf ( src: unknown ) |
alias typeOf ( src: unknown, extended: boolean = false ) |
Listed below are the parameter(s) for the method.
Param Name | Type | Description |
---|---|---|
src | unknown | The source to test for type. |
extended | boolean | Extends the return type string to include name. i.e 'function foo'. Defaults to false. |
Below is the return type for the method.
Return Type | Description |
---|---|
string | A string representing the correct type of the src. If ( extended = true ) then string will return with name. i.e 'function foo' |
- null
- undefined
- boolean
- number
- string
- symbol --- (Available from ES2015)
- bigint --- (Available from ES2020)
- array --- (Added with type_of() module)
- object
- anonymous functions --- ('function anonymous')
- function names --- ('function foo')
- class names --- ('function classname')
- internal javascript function names --- ('function eval')
- error names --- ('error RangeError', 'function RangeError')
- number names --- ('number integer', 'number float', 'number nan', 'number infinity', 'number bigint')
- string literal vs string Object --- ('string') for literal, ('string Object') for new String('foo')
Examples will be shown below, but can also be found as assertion tests in the mod_test.ts file.
While type_of() cant check for unknown types that spit out ReferenceErrors, you can always be safe by starting your check like so.
window.foo && type_of(foo);
Below is a string response list for using the type_of() method.
Example | Response |
---|---|
type_of ( unknown ) | "unknown" |
type_of ( undefined ) | "undefined" |
type_of ( void 0 ) | "undefined" |
type_of ( null ) | "null" |
type_of ( true ) | "boolean" |
type_of ( 12345 ) | "number" |
type_of ( "foo" ) | "string" |
type_of ( Symbol() ) | "symbol" |
type_of ( BigInt('9007199254740995') ) | "bigint" |
type_of ( [] ) | "array" |
type_of ( {} ) | "object" |
type_of ( JSON ) | "json" |
type_of ( Math ) | "math" |
type_of ( /a-z/ ) | "regexp" |
type_of ( function foo() { } ) | "function" |
type_of ( () => { } ) | "function" |
type_of ( class foo { } ) | "function" |
type_of ( NaN ) | "number" |
type_of ( Infinity ) | "number" |
type_of ( window ) | "window" |
type_of( globalThis ) | "window" |
type_of ( eval ) | "function" |
type_of ( Date ) | "function" |
type_of ( Error ) | "function" |
type_of ( new Error() ) | "error" |
type_of ( new RangeError() ) | "error" |
Below is an extended response list for type_of (src, true)
Example | Response |
---|---|
type_of ( "foo", true ) | "string" |
type_of ( {}, true ) | "object Object" |
type_of ( Date, true ) | "function Date" |
type_of ( eval, true ) | "function eval" |
type_of ( function foo(){}, true ) | "function foo" |
type_of ( () => {}, true ) | "function anonymous" |
type_of ( class foo {}, true ) | "function foo" |
type_of ( new class foo {}, true ) | "object foo" |
type_of ( Error, true ) | "function Error" |
type_of ( new Error(), true ) | "error Error" |
type_of ( RangeError, true ) | "function RangeError" |
type_of ( new RangeError(), true ) | "error RangeError" |
type_of ( 0, true ) | "number" |
type_of ( 12345, true ) | "number integer" |
type_of ( -12345, true ) | "number integer" |
type_of ( 12345.67, true ) | "number float" |
type_of ( -12345.67, true ) | "number float" |
type_of ( NaN, true ) | "number nan" |
type_of ( Infinity, true ) | "number infinity" |
type_of ( BigInt('9007199254740995'), true ) | "number bigint" |
type_of ( 1.0, true ) | "number integer" <-- Internal js error |
type_of ( new String('foo'), true ) | "string Object" |
There is an internal issue with JavaScript where floats starting or ending with zero get truncated off. So 1.0 reports as 1 and 1.01 reports as 1.01. I would love to fix this issue, but it's internal JavaScript. Only way to keep this precision is by keeping everything string.
type_of( 1.0, true ) === 'number integer' // <--- This is an error, because it should be a float.
// Should return this:
type_of ( 1.0, true ) === 'number float'
- v2.1.0 --- Added new features for number and string.
- Added in extended support for number. Now type_of () can return ('number integer', 'number float', 'number nan', 'number infinity', 'number bigint')
- Added in extended support for string literal vs string Object. Now type_of () can return ('string', 'string Object')
- Added in a .mjs module file written in javascript.
- v2.0.0 --- Importable Method type_of () or alias typeOf () with only one return type of (string)
- v1.0.0 --- Global method type_of () with extended return type of (string | type_of_value)
- This project was based on this tutorial.
- Thanks to Angus croll
Created by Adam Smith @Codevendor - feel free to contact me!
This project is open source and available under the ... MIT License.