type_of
An importable TypeScript method to fix the JavaScript typeof operator. This code is written as a module for the deno runtime.
Table of Contents
- General Info
- Features
- Tech
- Screenshots
- Setup
- Usage
- Examples
- Versions
- Acknowledgements
- Contact
- License
General Info
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.
Features
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');
Tech
- Deno - version 1.25.0
- TypeScript - version 4.7.4
- V8 - version 10.4.132.20
- Visual Studio Code - 1.70+
Screenshots
Setup
Things you will need to get this module running. You will need to install Deno runtime for Javascript / TypeScript.
Installing code from github
# git clone git@github.com:Codevendor/type_of.git
Installing code from deno.land with import statement.
// Snake case version - type_of();
import { type_of } from "https://deno.land/x/type_of@v2.0.0/mod.ts";
// Or
// Camel case alias - typeOf()
import { typeOf } from "https://deno.land/x/type_of@v2.0.0/mod.ts";
Usage
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.
Method - type_of ( src: unknown, extended: boolean = false )
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' |
Javascript Primitive Types:
- null
- undefined
- boolean
- number
- string
- symbol --- (Available from ES2015)
- bigint --- (Available from ES2020)
- array --- (Added with type_of() module)
Javascript Complex Type:
- object
Extended types in type_of() module with ( extended = true )
- 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
Examples will be shown below, but can also be found as assertion tests in the mod_test.ts file.
Type: unknown
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);
Type Response List
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" |
Type Response List with ( extended = true )
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 ( 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" |
Unsolved Number Types
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'
Versions
- 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')
- 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)
Acknowledgements
- This project was based on this tutorial.
- Thanks to Angus croll
Contact
Created by Adam Smith @Codevendor - feel free to contact me!
License
This project is open source and available under the ... MIT License.