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

@sylphx/synth-typecheck

v0.2.3

Published

Type checker for Synth AST - cross-language type inference and validation

Readme

@sylphx/synth-typecheck

Type checker for Synth AST - cross-language type inference and validation.

Features

  • Type Inference - Automatically infer types from AST
  • 🎯 Universal Types - Works across all languages
  • 🚀 Language-Agnostic - Built on Synth's universal AST
  • 📊 Type Compatibility - Check if types are compatible
  • 🔍 Error Detection - Find type errors in code
  • Fast - Leverages Synth's performance-optimized AST

Installation

npm install @sylphx/synth-typecheck

Usage

Quick Start

import { check } from '@sylphx/synth-typecheck'
import { parse } from '@sylphx/synth-js'

const tree = parse(`
const x = 42;
const y = "hello";
const z = x + y;  // Type error: number + string
`)

const result = check(tree)

console.log(result.success)  // false
console.log(result.errors)   // [{ message: ..., nodeId: ... }]

// Get inferred types
for (const [nodeId, type] of result.types) {
  console.log(`Node ${nodeId}: ${type.kind}`)
}

Type Checker API

import { TypeChecker } from '@sylphx/synth-typecheck'

const checker = new TypeChecker()
const result = checker.check(tree)

// Get type for specific node
const type = checker.getType(nodeId)
console.log(type.kind)  // 'number', 'string', etc.

// Check type compatibility
const compatible = checker.isCompatible(type1, type2)

Type System

Supported Type Kinds

type TypeKind =
  | 'any'          // Any type
  | 'unknown'      // Unknown type
  | 'never'        // Never type
  | 'void'         // Void type
  | 'null'         // Null
  | 'undefined'    // Undefined
  | 'boolean'      // Boolean
  | 'number'       // Number
  | 'string'       // String
  | 'symbol'       // Symbol
  | 'bigint'       // BigInt
  | 'object'       // Object
  | 'array'        // Array
  | 'function'     // Function
  | 'class'        // Class
  | 'interface'    // Interface
  | 'union'        // Union type
  | 'intersection' // Intersection type
  | 'tuple'        // Tuple
  | 'literal'      // Literal type
  | 'generic'      // Generic type
  | 'reference'    // Type reference

Type Structure

interface Type {
  kind: TypeKind
  name?: string                  // For named types
  elementType?: Type             // For arrays
  parameterTypes?: Type[]        // For functions
  returnType?: Type              // For functions
  properties?: Map<string, Type> // For objects
  types?: Type[]                 // For unions
  value?: unknown                // For literals
  nullable?: boolean
  optional?: boolean
}

Examples

Literal Types

import { check } from '@sylphx/synth-typecheck'
import { parse } from '@sylphx/synth-js'

// Number literal
const tree1 = parse('42')
const result1 = check(tree1)
// Type: { kind: 'number', value: 42 }

// String literal
const tree2 = parse('"hello"')
const result2 = check(tree2)
// Type: { kind: 'string', value: 'hello' }

// Boolean literal
const tree3 = parse('true')
const result3 = check(tree3)
// Type: { kind: 'boolean', value: true }

// Null literal
const tree4 = parse('null')
const result4 = check(tree4)
// Type: { kind: 'null' }

Array Types

const tree = parse('[1, 2, 3]')
const result = check(tree)

// Type: { kind: 'array', elementType: { kind: 'number' } }

Object Types

const tree = parse('{ x: 1, y: "hello" }')
const result = check(tree)

// Type: {
//   kind: 'object',
//   properties: Map {
//     'x' => { kind: 'number' },
//     'y' => { kind: 'string' }
//   }
// }

Binary Expressions

// Arithmetic
const tree1 = parse('1 + 2')
const result1 = check(tree1)
// Type: { kind: 'number' }

// String concatenation
const tree2 = parse('"a" + "b"')
const result2 = check(tree2)
// Type: { kind: 'string' }

// Comparison
const tree3 = parse('1 < 2')
const result3 = check(tree3)
// Type: { kind: 'boolean' }

Unary Expressions

// Negation
const tree1 = parse('!true')
const result1 = check(tree1)
// Type: { kind: 'boolean' }

// Typeof
const tree2 = parse('typeof x')
const result2 = check(tree2)
// Type: { kind: 'string' }

// Numeric
const tree3 = parse('-42')
const result3 = check(tree3)
// Type: { kind: 'number' }

Logical Expressions

const tree = parse('true && false')
const result = check(tree)

// Type: { kind: 'boolean' }

Variable Declarations

const tree = parse('const x = 42')
const result = check(tree)

// Variable 'x' inferred as: { kind: 'number' }

Function Types

const tree = parse('function add(a, b) { return a + b; }')
const result = check(tree)

// Type: {
//   kind: 'function',
//   parameterTypes: [{ kind: 'any' }, { kind: 'any' }],
//   returnType: { kind: 'any' }
// }

Type Compatibility

Check Compatibility

import { TypeChecker } from '@sylphx/synth-typecheck'

const checker = new TypeChecker()

const num = { kind: 'number' }
const str = { kind: 'string' }
const any = { kind: 'any' }

checker.isCompatible(num, num)  // true
checker.isCompatible(num, str)  // false
checker.isCompatible(num, any)  // true (any is compatible with everything)

Array Compatibility

const checker = new TypeChecker()

const numArray = {
  kind: 'array',
  elementType: { kind: 'number' }
}

const strArray = {
  kind: 'array',
  elementType: { kind: 'string' }
}

checker.isCompatible(numArray, numArray)  // true
checker.isCompatible(numArray, strArray)  // false

Type Errors

interface TypeError {
  message: string
  nodeId?: NodeId
  expected?: Type
  actual?: Type
  location?: {
    line: number
    column: number
  }
}

Example

const tree = parse('const x: number = "hello"')
const result = check(tree)

if (!result.success) {
  for (const error of result.errors) {
    console.error(error.message)
    console.error(`Expected: ${error.expected?.kind}`)
    console.error(`Actual: ${error.actual?.kind}`)
  }
}

Advanced Usage

Custom Type Environment

import { TypeChecker } from '@sylphx/synth-typecheck'

const checker = new TypeChecker()

// Type environment is automatically created with built-ins
// You can extend it by checking code that declares types

Get All Inferred Types

const result = check(tree)

for (const [nodeId, type] of result.types) {
  const node = tree.nodes[nodeId]
  console.log(`${node.type}: ${type.kind}`)
}

Integration with Linter

import { check } from '@sylphx/synth-typecheck'
import { createLinter } from '@sylphx/synth-lint'

const tree = parse(code)

// Type check first
const typeResult = check(tree)
if (!typeResult.success) {
  console.error('Type errors found!')
}

// Then lint
const linter = createLinter()
const lintResult = linter.lint(tree)

Use Cases

  • Type validation - Ensure code is type-safe
  • Type inference - Automatically determine types
  • IDE support - Power autocomplete and type hints
  • Code analysis - Detect type-related issues
  • Cross-language checking - Universal type system
  • Documentation - Generate type docs
  • Refactoring - Safe type-preserving refactors

Supported Languages

Works on any language parsed by Synth:

  • JavaScript
  • TypeScript
  • Python
  • Go
  • Rust
  • And more...

The type checker adapts to each language's type system through the universal AST.

Limitations

This is a basic type inference system. It:

  • ✅ Infers literal types
  • ✅ Infers array and object types
  • ✅ Infers expression result types
  • ✅ Handles variable declarations
  • ❌ Does not perform advanced type narrowing
  • ❌ Does not handle complex generics
  • ❌ Does not perform full flow analysis

For production TypeScript type checking, use the official TypeScript compiler. This type checker is designed for cross-language analysis and basic type inference.

Performance

Leverages Synth's performance-optimized AST:

  • Single-pass type inference
  • O(1) node access
  • Efficient type representation
  • Minimal memory overhead

API Reference

check(tree)

Check types in a tree and return result.

const result = check(tree)

TypeChecker

Advanced type checker with state.

const checker = new TypeChecker()
const result = checker.check(tree)
const type = checker.getType(nodeId)
const compatible = checker.isCompatible(type1, type2)

createChecker()

Factory function to create a type checker.

const checker = createChecker()

License

MIT


Note: This is a universal type checker for basic type inference across languages. For advanced TypeScript checking, use the official TypeScript compiler.