SqlType
infers the result type of a SQL query at compile time, using only TypeScript's type system.
SqlType is a static SQL analysis and inference engine implemented entirely with TypeScript’s type system. it parses SQL-like query strings at compile time and infers the resulting data shape based on a provided schema. the system supports validation of selectors, function calls, joins, aliases, and SELECT * semantics - all within the type layer of TypeScript, with zero runtime logic. SqlType helps developers catch query issues during development, creating safer and more predictable data access layers in TypeScript-based systems.
features
-
compile-time SQL parsing
parses and analyzes SQL queries entirely at the type level using recursive conditional types.
-
full query shape inference
infers result structures from
SELECTqueries, including expressions and function calls. -
support for joins and aliases
supports
INNER,LEFT,RIGHT, andFULL OUTER JOINs with alias resolution and field mapping. -
function usage validation
functions like
COUNT(...)are checked at compile time for valid argument types and nesting. -
zero-runtime
no runtime dependency; the entire system works within TypeScript’s type checker.
usage
// Example 1: Simple SELECT with alias
type Tables = {
users: {
id: number;
name: string;
};
};
type Query = "SELECT users.name AS username FROM users";
type Result = BuildQuery<Query, Tables>;
/*
Result:
{
username: string;
}
*/// Example 2: COUNT aggregation with JOIN
type Tables = {
users: {
id: number;
name: string;
};
posts: {
id: number;
user_id: number;
};
};
type Query = "SELECT COUNT(posts.id) AS totalPosts FROM users LEFT JOIN posts ON users.id = posts.user_id";
type Result = BuildQuery<Query, Tables>;
/*
Result:
{
totalPosts: number;
}
*/// Example 3: Multiple columns with alias and join
type Tables = {
users: {
id: number;
name: string;
};
posts: {
id: number;
user_id: number;
title: string;
};
};
type Query = "SELECT u.name AS username, COUNT(p.id) AS total FROM users u LEFT JOIN posts p ON u.id = p.user_id";
type Result = BuildQuery<Query, Tables>;
/*
Result:
{
username: string;
total: number;
}
*/ stack
TypeScript, TypeScript type-level programming