Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

tinspector

Package Overview
Dependencies
Maintainers
1
Versions
194
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tinspector

TypeScript type inspector

  • 2.3.1
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

tinspector

Build Status Coverage Status Greenkeeper badge

An introspection (reflection) library, extract JavaScript/TypeScript type into metadata information such as class name, methods, parameters and their appropriate data types

Example

import reflect from "tinspector"

class Awesome{
    awesome(){}
}

class MyAwesomeClass extends Awesome {
    @decorateMethod({ cache: "20s" })
    myAwesomeMethod(stringPar:string, numberPar:number): number {
        return Math.random()
    }
}

const metadata = reflect(MyAwesomeClass)

Result of metadata variable above is like below

{
    kind: 'Class',
    name: 'MyAwesomeClass',
    type: MyAwesomeClass,
    decorators: [],
    properties: [],
    ctor: {
        kind: 'Constructor',
        name: 'constructor',
        parameters: []
    },
    methods: [
        {
            kind: 'Method',
            name: 'myAwesomeMethod',
            parameters: [
                {
                    kind: 'Parameter',
                    name: 'stringPar',
                    type: String,
                    decorators: [],
                    properties: {}
                },
                {
                    kind: 'Parameter',
                    name: 'numberPar',
                    type: Number,
                    decorators: [],
                    properties: {}
                }
            ],
            decorators: [{ cache: '20s' }],
            returnType: Number,
        },
        {
            kind: 'Method',
            name: 'awesome',
            parameters: [],
            decorators: [],
            returnType: undefined,
        }
    ]
}

Features

  • Inspect function
  • Inspect module or file
  • Inspect class
  • Inspect class with inheritance
  • Inspect getter and setter
  • Inspect methods
  • Inspect parameters
  • Supported inspect destructured parameter
  • Supported inspect rest parameter
  • Supported inspect parameter with complex default value
  • (TypeScript only) Inspect decorators
  • (TypeScript only) Inspect parameter properties
  • (TypeScript only) Inspect type information
  • (TypeScript only) Configurable decorator (inheritable / allow multiple)

TypeScript Requirement

To be able to inspect type information its required to enable configuration below in tsconfig.json

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true           
  }
}

Inspect Type Information

TypeScript when emitDecoratorMetadata enabled, TypeScript will add type information during compile time. This make it possible to extract typescript type information during runtime.

CAVEAT

TypeScript emitDecoratorMetadata has some limitation.

  • Declaration should have at least one decorator to get metadata (type information)
  • Array element type information not included.
  • Generic type information not included.

Based on limitation above its required at least have one decorator to make tinspector to be able to extract type information:

import reflect from "tinspector"

class Awesome {
    @reflect.noop()
    awesome(multiply:number): number { return 1 }
}

const metadata = reflect(Awesome)

tinspector will be able to get type information of the method's return type and parameters of the awesome method above. Note that we applied @reflect.noop() decorator on the awesome method. @reflect.noop() does nothing except to force TypeScript to emit metadata information.

import reflect from "tinspector"

class Awesome {
    @reflect.noop()
    aweProperty:number
}

const metadata = reflect(Awesome)

Above code showing that we able to get type information of a property.

import reflect from "tinspector"

@reflect.noop()
class Awesome {
    constructor(multiply:number){}
}

const metadata = reflect(Awesome)

Above code showing that we able to get type information of parameters of the constructor, by applying decorator on the class level.

Inspect Array and Generic Type

To get type information of an Array and Generic type its required to use @reflect.type() decorator on the declaration.

import reflect from "tinspector"

class Awesome {
    @reflect.type([Number])
    awesome(multiply:number): Array<number> {}
}

const metadata = reflect(Awesome)

Above code showing that we able to get method's return type information by providing @reflect.type([Number]). Note that the [Number] is an array of Number.

import reflect from "tinspector"

class Option { 
    data:string
}

class Awesome {
    @reflect.type(Option)
    awesome(multiply:number): Partial<Option> {}
}

const metadata = reflect(Awesome)

We will be able to get generic type information such as Partial, Required etc by applying @reflect.type() like above.

Inspect Parameter Properties

TypeScript has parameter properties feature, which make it possible to use constructor parameter as property. tinspector able to extract parameter properties type information by using @reflect.parameterProperties() decorator.

import reflect from "tinspector"

@reflect.parameterProperties()
class Awesome {
    constructor(public multiply:number){}
}

const metadata = reflect(Awesome)

Custom Decorator

Tinspector able to extract classes/methods/properties/parameters decorated with predefined decorators. There are predefined decorators should be use to be able for Tinspector to inspect the decorators

DecoratorDescription
decorateClassDecorate class with object specified in parameter
decoratePropertyDecorate property with object specified in parameter
decorateMethodDecorate method with object specified in parameter
decorateParameterDecorate parameter with object specified in parameter
decorateDecorate any (class, property, method, parameter) with object specified in parameter
mergeDecoratorMerge multiple decorators into one, useful on creating custom decorator

Example usage

import { decorateClass, decorateProperty } from "tinspector"

@decorateClass({ message: "hello world" })
class Awesome {
    @decorateProperty({ message: "awesome!" })
    awesome: number = 10
}

Parameter passed on each decorator can be any object contains value, methods etc, those value will be returned when the class metadata extracted.

Create your own custom decorator by creating function returns decorator above

import { decorateMethod } from "tinspector"

// create custom decorator
function cache(duration:number){
    return decorateMethod({ type: "Cache", duration })
}

class Awesome{
    @cache() // use it like usual decorator
    awesome(){}
}

Use mergeDecorator to combine multiple decorator on custom decorator

import { decorateMethod, mergeDecorator } from "tinspector"

// create custom decorator
function cacheAndDelay(duration:number){
    return mergeDecorator([
        decorateMethod({ type: "Cache", duration }), 
        decorateMethod({ type: "Delay", duration })
    ])
}

Decorator Option (Inheritance, Allow Multiple)

Decorator can be further configured to match the behavior you need like below.

decorateMethod(<data>, <option>)

Option is a simple object with properties:

  • inherit Boolean If false decorator will not be merged on the derived class. Default true
  • allowMultiple Boolean If false throw error when multiple decorator applied on class. Also when set false will prevent super class decorator being merged into derived class when already exists. When set false, decorator required to have DecoratorId property to identify the similar decorator.

Example disable decorator inheritance

@decorateClass({ log:true }, { inherit: false })
class Awesome {
    awesome(){}
}

// { log: true} will not inherited on this class
class IamAwesome extends Awesome{ }

Example disable multiple decorator on inheritance

import { DecoratorId, decorateClass } from "tinspector"

function log(){
    return @decorateClass({ [DecoratorId]: "logging",  log:true }, { allowMultiple: false })
}

@log()
class Awesome {
    awesome(){}
}

// parent decorator will not merged
// guaranteed derived class only have single decorator with specific ID
@log()
class IamAwesome extends Awesome{ }

Keywords

FAQs

Package last updated on 15 Mar 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc