npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ts-ref-kit

v1.2.0

Published

Type reflection and validation library for TypeScript

Readme

ts-ref-kit

TypeScript type reflection and validation library for runtime access and usage of TypeScript type information.

Features

  • Type Reflection: Retrieve metadata for TypeScript classes, interfaces, type aliases, and enums at runtime
  • Type Validation: Validate whether values conform to specific TypeScript type definitions
  • JSON Conversion: Convert JSON strings to class instances
  • Type Queries: Query inheritance relationships, interface implementations, and more between classes
  • Generic Support: Support for reflection and validation of generic types
  • Enum Handling: Access enum names, values, and type definitions

Installation

npm install ts-ref-kit

Quick Start

Type Reflection Example

import { getClassDefinition, getInterfaceDefinition, getTypeAliasDefinition, getEnumDefinition } from 'ts-ref-kit'

// Get class definition
const classDef = getClassDefinition('MyClass')
console.log(classDef?.name) // Output: class name
console.log(classDef?.properties) // Output: class properties list
console.log(classDef?.methods) // Output: class methods list

// Get interface definition
const interfaceDef = getInterfaceDefinition('MyInterface')
console.log(interfaceDef?.name) // Output: interface name
console.log(interfaceDef?.properties) // Output: interface properties list
console.log(interfaceDef?.methods) // Output: interface methods list

// Get type alias definition
const typeAliasDef = getTypeAliasDefinition('MyTypeAlias')
console.log(typeAliasDef?.name) // Output: type alias name
console.log(typeAliasDef?.type) // Output: type definition

// Get enum definition
const enumDef = getEnumDefinition('MyEnum')
console.log(enumDef?.name) // Output: enum name
console.log(enumDef?.members) // Output: enum members

Type Validation Example

import { isType, assertType } from 'ts-ref-kit'

// Validate if value matches type
const value = 'test'
const isString = isType(value, 'string')
console.log(isString) // Output: true

// Assert value matches type (throws error if not)
assertType<string>(value, 'string')

// Validate a reflected interface
interface User {
    name: string
    age: number
}

const user = { name: 'John', age: 30 }
const isUser = isType(user, 'User')
console.log(isUser) // Output: true

JSON Conversion Example

import { JSONTransfer } from 'ts-ref-kit'

class User {
    name: string
    age: number

    constructor() {
        this.name = ''
        this.age = 0
    }
}

const jsonString = '{"name":"John","age":30}'
const jsonTransfer = new JSONTransfer()

// Convert JSON string to class instance
const user = jsonTransfer.parse<User>(jsonString, 'User')
console.log(user instanceof User) // Output: true
console.log(user.name) // Output: John
console.log(user.age) // Output: 30

Enum Operations Example

import { getEnumNames, getEnumValues } from 'ts-ref-kit'

enum Color {
    Red,
    Green,
    Blue
}

// Get enum names list
const colorNames = getEnumNames('Color')
console.log(colorNames) // Output: ['Red', 'Green', 'Blue']

// Get enum values list
const colorValues = getEnumValues({ Color })
console.log(colorValues) // Output: [0, 1, 2]

API Documentation

Core Type Definitions

  • TypeDefinition: Core interface representing TypeScript types
  • ClassDefinition: Definition for class types
  • InterfaceDefinition: Definition for interface types
  • TypeAliasDefinition: Definition for type aliases
  • EnumDefinition: Definition for enum types

Type Reflection API

Class Related

  • getClassDefinition(arg: Constructor | object | string): ClassDefinition | undefined
  • getClassByName(className: string): Constructor | undefined

Interface Related

  • getInterfaceDefinition(name: string): InterfaceDefinition | undefined

Type Alias Related

  • getTypeAliasDefinition(name: string, genericArgs?: TypeDefinition[]): TypeAliasDefinition | undefined

Enum Related

  • getEnumDefinition(name: string): EnumDefinition | undefined
  • getEnumNames(enumName: string): string[]
  • getEnumValues(args: { [enumName: string]: Record<string, string | number> }): (string | number)[]

Type Utilities

  • getTypeDef(type: Type | TypeDefinition): TypeDefinition
  • TypeDefinition.isPrimitiveType(type: TypeDefinition): boolean
  • TypeDefinition.isArrayType(type: TypeDefinition): boolean
  • TypeDefinition.isLiteralType(type: TypeDefinition): boolean
  • TypeDefinition.isTypeLiteralType(type: TypeDefinition): boolean
  • TypeDefinition.isUnionType(type: TypeDefinition): boolean
  • TypeDefinition.isIntersectionType(type: TypeDefinition): boolean
  • TypeDefinition.isTupleType(type: TypeDefinition): boolean
  • TypeDefinition.isClassDefinition(type: TypeDefinition): boolean
  • TypeDefinition.hasGenerics(type: TypeDefinition): boolean

Type Validation API

  • isType(value: unknown, type: Type | TypeDefinition, depth: number = 5): boolean
  • assertType<T>(data: unknown, type: Type, depth: number = 5): T
  • validateValue(value: unknown, typeDef: TypeDefinition, depth: number = 1): ValidateResult

JSON Conversion API

  • JSONTransfer class
    • parse<T = unknown>(jsonString: JSONString<T>, type?: Type): T

Configuration Options

import { ReflectConfig } from 'ts-ref-kit'

// Validation error handler
ReflectConfig.validationErrorHandler = e => {
    console.error(e.message)
    console.error(e.failureResult?.errorStackFlow)
}

// Whether to enable validation
ReflectConfig.validation = true

// Whether to enable debug mode
ReflectConfig.debug = false

Advanced Usage

Generic Type Handling

import { getTypeDef } from 'ts-ref-kit'

// Get a generic type definition
const mapType = getTypeDef('Map<string, number>')
console.log(mapType.name) // Output: Map
console.log(mapType.generics?.[0].name) // Output: string
console.log(mapType.generics?.[1].name) // Output: number

// Get a reflected type by name
const userType = getTypeDef('User')
console.log(userType.classDefinition?.name || userType.interfaceName || userType.typeAliasName)

Type Relationship Queries

import { getClassDefinition } from 'ts-ref-kit'

// Query if a class is a subclass of another class
const classDef = getClassDefinition('MyClass')
const isSubClass = classDef?.isSubClassOf('BaseClass')

// Query if a class is a superclass of another class
const isSuperClass = classDef?.isSuperClassOf('DerivedClass')

Special Type Registration

import { registerSpecialType } from 'ts-ref-kit'

// Register custom special type
registerSpecialType({
    name: 'MySpecialType',
    genericParams: ['T'],
    getType(typeArg) {
        return typeArg
    }
})

Parser Configuration

The core functionality of ts-ref-kit relies on type metadata generated at compile time. The parser module provides integration capabilities with different build tools to extract type information and generate metadata during compilation.

Vite Plugin

In Vite projects, you can use reflectParserPlugin to automatically generate type metadata:

import { defineConfig } from 'vite'
import { reflectParserPlugin } from 'ts-ref-kit/parser'

export default defineConfig({
    plugins: [
        reflectParserPlugin({
            entry: 'src/main.ts',
            sourcePaths: 'src'
        })
    ]
})

When multiple independently built projects run in the same browser or Node.js context, assign each project a separate reflect module. default is only safe for a single project/build output; if multiple outputs all write metadata to default, the last one loaded may overwrite the others.

// vite.config.ts
reflectParserPlugin({
    entry: 'src/main.ts',
    sourcePaths: 'src',
    reflectModule: 'project-a'
})

Shared runtime usage

// src/reflect.ts
import { getReflectModule } from 'ts-ref-kit'

export const reflect = getReflectModule('project-a')
export const ReflectClass = reflect.ReflectClass
export const ReflectValidate = reflect.ReflectValidate
import { reflect } from './reflect'

reflect.getClassDefinition('User')
reflect.isType(user, 'User')

Use this style when several packages share the same ts-ref-kit runtime, for example when libraries depend on the application's installed copy. In this scenario, avoid setReflectModule for isolation: it changes the shared default module name and can affect other packages using the same runtime.

Bundled runtime compatibility

If a package bundles its own copy of ts-ref-kit, its default module state is local to that bundled copy. Existing code that uses top-level APIs can be kept by setting the module once at package startup:

// package entry
import { setReflectModule } from 'ts-ref-kit'

setReflectModule('project-a')

After that, top-level APIs in that bundled package use project-a:

import { getClassDefinition, isType } from 'ts-ref-kit'

getClassDefinition('User')
isType(user, 'User')

This compatibility style is intended for bundled/inline runtimes. For shared runtimes, prefer the explicit getReflectModule(name) API shown above.

Custom Build Configuration

If you're using other build tools or a custom build process, you can directly use reflectLoader:

import { reflectLoader } from 'ts-ref-kit/parser'

const loader = reflectLoader({
    sourcePaths: 'src',
    reflectModule: 'project-a',
    exclude: /node_modules/,
    outputLog: true
})

// Transform a single file
const transformedCode = loader.transform(sourceCode, sourceFileName)

// Generate metadata injection code for the entry module
const metadataCode = loader.outputAllMetas()

Parser Options

  • entry: Entry file path of the project
  • sourcePaths: Source code paths to process, can be a string or array of strings
  • exclude: File paths to exclude, can be a string, regular expression, or array of them
  • forEnabledClassOnly: Whether to only process classes that implement the EnableReflect interface
  • outputLog: Whether to output log information
  • reflectModule: Optional reflect module name for isolating metadata. Use a unique value for each independently built project/package that can run in the same browser or Node.js context.

Working Principle

  1. The parser scans TypeScript source code during compilation
  2. Extracts definitions of classes, interfaces, enums, and type aliases
  3. Generates type metadata and injects it into the compiled code
  4. Runtime access to this metadata is available through ts-ref-kit APIs

Node.js Environment Usage

In Node.js environments, you can directly use the parser to analyze TypeScript files and generate injection code:

const { reflectLoader } = require('ts-ref-kit/parser')
const fs = require('fs')

const sourceCode = fs.readFileSync('src/types.ts', 'utf8')
const loader = reflectLoader({
    sourcePaths: 'src',
    reflectModule: 'project-a'
})

const transformedCode = loader.transform(sourceCode, 'src/types.ts')
const metadataCode = loader.outputAllMetas()

console.log(metadataCode)

You can also initialize reflection directly in Node.js with setupReflectTypes. The reflectModule option is optional and defaults to default, but it should match the runtime module name when you isolate multiple projects:

const { setupReflectTypes } = require('ts-ref-kit/parser')
const { getReflectModule } = require('ts-ref-kit')

await setupReflectTypes({
    filePaths: ['src'],
    sourceFolder: process.cwd(),
    distFolder: process.cwd(),
    reflectModule: 'project-a'
})

const reflect = getReflectModule('project-a')
const classDef = reflect.getClassDefinition('User')

Development

Install Dependencies

npm install

Build Project

npm run build

Run Lint

npm run lint

License

MIT