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

query-typed

v1.0.0

Published

TypeScript SQL query parser with compile-time column type extraction

Downloads

14

Readme

query-typed

🚀 TypeScript SQL query parser with compile-time column type extraction

npm version License: ISC TypeScript

개요

query-typed는 TypeScript에서 SQL 쿼리의 컬럼 타입을 컴파일 타임에 추출할 수 있는 혁신적인 라이브러리입니다. 실행 없이도 SQL 쿼리에서 정확한 컬럼 타입을 추론하여 타입 안전한 개발을 가능하게 합니다.

🌟 주요 특징

  • 🚀 컴파일 타임 타입 추론: 실행 없이 SQL 쿼리에서 컬럼 타입 자동 추출
  • 🔒 타입 안전성: 잘못된 컬럼 사용 시 컴파일 에러로 사전 방지
  • 제로 런타임 오버헤드: 타입 추론은 컴파일 타임에만 발생
  • 🎯 IDE 지원: 자동완성, 타입 힌트, 리팩토링 지원
  • 📦 제로 의존성: 외부 라이브러리 없이 순수 TypeScript 타입만 사용
  • 📝 다양한 SQL 지원: 별칭, 함수, 집계, 표현식 등 포괄적 지원

🎯 v1.2.0의 주요 기능

  • 🚀 컴파일 타임 SQL 파싱: TypeScript 템플릿 리터럴 타입을 사용한 타입 레벨 SQL 분석
  • 🔒 타입 안전성 극대화: 실행 없이도 컴파일 타임에 SQL 컬럼 타입 추론
  • ⚡ 제로 런타임 비용: 타입 추론은 빌드 타임에만 발생, 런타임 의존성 없음
  • 🎯 개발 경험 향상: IDE 자동완성 및 타입 힌트 지원
  • 📦 순수 TypeScript: 외부 라이브러리 의존성 없이 타입 시스템만 활용
  • 📝 포괄적 SQL 지원: 별칭, 함수, 집계, 표현식, 테이블 조인 등

📦 설치

npm install query-typed
# 또는
yarn add query-typed
# 또는
pnpm add query-typed

요구사항: TypeScript 4.1+ (템플릿 리터럴 타입 지원)

제로 의존성: 외부 라이브러리 없이 순수 TypeScript 타입만 사용합니다!

🚀 빠른 시작

컴파일 타임 타입 추론

import { ExtractColumns, createTypedQuery } from 'query-typed';

// 1. 타입만 추출 (실행 없이 컴파일 타임에 추론!)
type UserColumns = ExtractColumns<'SELECT id, name, email FROM users'>;
// UserColumns 타입: ["id", "name", "email"]

// 2. 타입 안전한 쿼리 생성
const query = createTypedQuery('SELECT id, name, email FROM users');
// query.columns의 타입이 자동으로 ["id", "name", "email"]로 추론됨

// 3. 별칭 처리
type AliasColumns = ExtractColumns<'SELECT id as user_id, name as user_name FROM users'>;
// AliasColumns 타입: ["user_id", "user_name"]

// 4. 집계 함수
type AggColumns = ExtractColumns<'SELECT COUNT(*) as total, SUM(amount) as sum_amount FROM orders'>;
// AggColumns 타입: ["total", "sum_amount"]

타입 안전한 쿼리 빌더

import { createTypedQuery, select } from 'query-typed';

// 타입 안전한 쿼리 생성
const query = createTypedQuery('SELECT id, name, email FROM users');
// query.columns의 타입이 자동으로 ["id", "name", "email"]로 추론됨

// SELECT 쿼리 빌더
const selectQuery = select('SELECT id as user_id, name FROM users WHERE status = ?');
// selectQuery.columns의 타입이 자동으로 ["user_id", "name"]로 추론됨

📚 상세 사용법

컴파일 타임 SQL 파싱 (TypeScript)

🚀 핵심 기능: TypeScript의 템플릿 리터럴 타입을 사용하여 실행 없이도 컴파일 타임에 SQL 쿼리에서 컬럼 타입을 추출할 수 있습니다!

import { ExtractColumns, ExtractTables, createTypedQuery } from 'query-typed';

// 1. 컴파일 타임에 컬럼 타입 추론
type UserColumns = ExtractColumns<'SELECT id, name, email FROM users'>;
// UserColumns 타입: ["id", "name", "email"]

type AliasColumns = ExtractColumns<'SELECT id as user_id, name as user_name FROM users'>;
// AliasColumns 타입: ["user_id", "user_name"]

type AggColumns = ExtractColumns<'SELECT COUNT(*) as total, SUM(amount) as sum_amount FROM orders'>;
// AggColumns 타입: ["total", "sum_amount"]

// 2. 타입 안전한 쿼리 생성
const typedQuery = createTypedQuery('SELECT id, name, email FROM users');
// typedQuery.columns의 타입이 자동으로 ["id", "name", "email"]로 추론됨

// 3. 타입 검증 함수
function expectColumns<Expected extends readonly string[]>(expected: Expected) {
    return function<T extends string>(sql: T): ExtractColumns<T> extends Expected ? T : never {
        return sql as any;
    };
}

// 컴파일 타임에 타입 검증
const validQuery = expectColumns(['id', 'name', 'email'])('SELECT id, name, email FROM users');
// ✅ 통과

const invalidQuery = expectColumns(['id', 'name'])('SELECT id, name, email FROM users');
// ❌ 컴파일 에러: 타입이 맞지 않음

// 4. WITH 절 (CTE) 지원
type WithColumns = ExtractColumns<'WITH v_tmp AS (SELECT user_idx, level FROM users) SELECT idx, level FROM v_tmp'>;
// WithColumns 타입: ["idx", "level"]

// 5. 실용적인 사용 예제
function createTypedSelectQuery<T extends string>(sql: T) {
    type Columns = ExtractColumns<T>;
    
    return {
        sql,
        columns: null as any as Columns,
        execute: async <TRecord = Record<string, any>>(): Promise<TRecord[]> => {
            // 실제 쿼리 실행 로직
            return [] as TRecord[];
        }
    };
}

const query = createTypedSelectQuery('SELECT id, name, created_at FROM users WHERE status = ?');
// query.columns의 타입: ["id", "name", "created_at"]

// WITH 절을 사용한 복잡한 쿼리도 지원
const withQuery = createTypedSelectQuery(`
    WITH user_stats AS (
        SELECT user_id, COUNT(*) as order_count, SUM(amount) as total_amount 
        FROM orders GROUP BY user_id
    )
    SELECT user_id as id, order_count, total_amount as total FROM user_stats
`);
// withQuery.columns의 타입: ["id", "order_count", "total"]

🔧 지원하는 SQL 기능

컴파일 타임 기능 (TypeScript)

  • 타입 추론: 실행 없이 컴파일 타임에 컬럼 타입 추출
  • 타입 안전성: 잘못된 컬럼 타입 사용 시 컴파일 에러
  • IDE 지원: 자동완성 및 타입 힌트 제공
  • 제로 런타임 비용: 런타임 오버헤드 및 의존성 없음
  • 개발 경험: 타입 기반 개발로 버그 사전 방지
  • 순수 TypeScript: 외부 라이브러리 없이 타입 시스템만 활용

지원하는 SQL 패턴

// ✅ 기본 컬럼
ExtractColumns<'SELECT id, name FROM users'>
// ["id", "name"]

// ✅ 별칭
ExtractColumns<'SELECT id as user_id FROM users'>
// ["user_id"]

// ✅ 집계 함수
ExtractColumns<'SELECT COUNT(*) as total FROM users'>
// ["total"]

// ✅ 일반 함수
ExtractColumns<'SELECT UPPER(name) FROM users'>
// ["UPPER(...)"]

// ✅ 테이블 접두사
ExtractColumns<'SELECT u.id FROM users u'>
// ["id"]

// ✅ 표현식
ExtractColumns<'SELECT age + 1 as next_age FROM users'>
// ["next_age"]

// ✅ WITH 절 (CTE - Common Table Expression)
ExtractColumns<'WITH v_tmp AS (SELECT user_idx, level FROM users) SELECT idx, level FROM v_tmp'>
// ["idx", "level"]

// ✅ 복잡한 WITH 절
ExtractColumns<'WITH stats AS (SELECT user_id, COUNT(*) as cnt FROM orders GROUP BY user_id) SELECT user_id as id, cnt as total FROM stats'>
// ["id", "total"]

🎯 고급 사용법

타입 안전성 검증

import { ExtractColumns } from 'query-typed';

// 타입 검증 함수
function expectColumns<Expected extends readonly string[]>(expected: Expected) {
    return function<T extends string>(sql: T): ExtractColumns<T> extends Expected ? T : never {
        return sql as any;
    };
}

// 컴파일 타임 검증 예제
const validQuery1 = expectColumns(['id', 'name', 'email'])('SELECT id, name, email FROM users');
console.log('✅ 유효한 쿼리:', validQuery1);

// 다음 줄의 주석을 해제하면 컴파일 에러가 발생합니다:
// const invalidQuery = expectColumns(['id', 'name'])('SELECT id, name, email FROM users');
// ❌ 컴파일 에러: 3개 컬럼을 2개로 검증하려고 함

// 조건부 타입을 사용한 쿼리 검증
type IsValidUserQuery<T extends string> = ExtractColumns<T> extends readonly string[]
    ? ExtractColumns<T>[number] extends 'id' | 'name' | 'email' | 'created_at' | 'updated_at'
        ? T
        : never
    : never;

function createUserQuery<T extends string>(sql: T): IsValidUserQuery<T> {
    // 사용자 테이블의 유효한 컬럼만 허용
    return sql as any;
}

const validUserQuery = createUserQuery('SELECT id, name FROM users');
console.log('✅ 유효한 사용자 쿼리:', validUserQuery);

// 다음 줄의 주석을 해제하면 컴파일 에러가 발생합니다:
// const invalidUserQuery = createUserQuery('SELECT invalid_column FROM users');
// ❌ 컴파일 에러: 유효하지 않은 컬럼

📖 예제

더 많은 예제는 examples 디렉토리를 참고하세요.

🧪 테스트

npm test                # 모든 테스트 실행
npm run test:watch      # 변경사항 감시하며 테스트
npm run test:coverage   # 커버리지 포함 테스트

📄 라이선스

ISC License

🤝 기여하기

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📝 변경 로그

v1.2.0

  • 🚀 컴파일 타임 SQL 파싱: ExtractColumns, ExtractTables 타입 추가
  • 🔧 런타임 SQL 파싱: extractColumns, extractTables 함수 추가
  • TypeScript 템플릿 리터럴 타입을 사용한 타입 레벨 SQL 분석
  • 실행 없이 컴파일 타임에 SQL 컬럼 타입 추론
  • 타입 안전한 쿼리 빌더 및 검증 함수 제공
  • node-sql-parser를 사용한 런타임 SQL 쿼리 분석 기능
  • 컬럼 별칭, 집계 함수, 일반 함수 지원
  • 테이블 별칭 및 JOIN 테이블 추출 지원
  • 포괄적인 테스트 케이스 추가

query-typed로 타입 안전한 SQL 개발을 시작하세요! 🚀