Show GN: TypeScript 기반 JSON Schema 구현과 개발 도구 모음

1 day ago 3

"내 취향의 타입 안전한 라이브러리를 만들어보자"는 마음으로 시작한 프로젝트입니다.

이 프로젝트는 타입 안전한 JSON Schema 구현체를 시작으로 개발 과정에서 필요한 다양한 도구들로 자연스럽게 확장되었습니다.

현재 구직을 위해 1차적으로 마침표를 찍어보았습니다.

프로젝트 원칙

다음과 같은 핵심 원칙을 준수하며 개발되었습니다:

  • 엄격한 타입 시스템 활용
  • 최소한의 외부 의존성 유지
  • 재사용 가능한 타입 시스템 설계
  • API 문서화
  • 높은 테스트 커버리지 유지
  • 순수 타입스크립트 구현

라이브러리

@imhonglu/json-schema

JSON Schema 2020-12 draft 사양을 준수하는 TypeScript 구현체입니다.

[IMG] demo-1

import { Schema, SchemaDefinition } from "@imhonglu/json-schema"; export const Address = new Schema({ type: "object", properties: { street: { type: "string" }, city: { type: "string" }, zip: { type: "string" }, }, required: ["street"] as const, }); export type Address = SchemaDefinition.Instance<typeof Address>; // { // street: string; // city?: string; // zip?: string; // }

@imhonglu/format

JSON Schema의 format 키워드를 구현하기 위해 시작된 프로젝트입니다.

import { FullTime } from '@imhonglu/format'; const time = FullTime.parse('00:00:00.000Z'); // { hour: 0, minute: 0, second: 0, secfrac: '.000', offset: undefined } console.log(time.toString()); // '00:00:00.000Z' console.log(JSON.stringify(time)); // '"00:00:00.000Z"' const result = FullTime.safeParse('invalid'); if (!result.ok) { console.error(result.error); }

@imhonglu/pattern-builder

RFC 스펙의 ABNF 문법 구현중 정규식의 가독성 향상을 위해 만들어진 regex 빌더입니다.

import { characterSet, concat, hexDigit } from "@imhonglu/pattern-builder"; // pct-encoded = "%" HEXDIG HEXDIG export const pctEncoded = concat( "%", hexDigit.clone().exact(2), ); // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" export const unreserved = characterSet( alpha, digit, /[\-._~]/, );

@imhonglu/type-guard

타입 가드의 가독성 향상을 위해 만들어진 타입 가드 라이브러리입니다.

import { composeGuards } from "@imhonglu/type-guard"; const is = composeGuards({ string: (value: unknown): value is string => typeof value === "string", number: (value: unknown): value is number => typeof value === "number" }); is.string("hello"); // true is.not.string(42); // true let value: string | number | undefined; if (is.number(value)) { value.toFixed(2); // 'value' is number } if (is.not.number(value)) { value.toFixed(2); // error: Property 'toFixed' does not exist on type 'undefined'. }

@imhonglu/type-object

네이티브 Object API의 타입 안전한 래퍼 라이브러리입니다. 네이티브 동작에 가까운 타입을 제공합니다.

import * as TypeObject from '@imhonglu/type-object'; const data = { a: 1, b: 2, c: 3 }; for (const key of TypeObject.keys(data)) { // key: "a" | "b" | "c" console.log(data[key]); // number } const string = 'hello'; for (const index of TypeObject.keys(string)) { // index: number & keyof string console.log(string[index]); // string }

@imhonglu/toolkit

프로젝트 내부에서 사용중인 유틸리티 타입과 유틸리티 함수들의 모음입니다.

import type { Fn } from '@imhonglu/toolkit'; // 함수 타입 '(...args: any[]) => any' 에 대한 타입 별칭을 제공합니다. Fn.Callable // (...args: any[]) => any // 제네릭을 통해 인자 유형만 정의할 수 있습니다. Fn.Callable<{ args: [number, number] }> // (...args: [number, number]) => any // 제네릭을 통해 반환 유형만 정의할 수 있습니다. Fn.Callable<{ return: string }> // (...args: any[]) => string // 제네릭을 통해 인자 유형과 반환 유형을 모두 정의할 수 있습니다. Fn.Callable<{ args: [number, number], return: string }> // (...args: [number, number]) => string

향후 계획 및 구직

진행 중인 프로젝트의 다음 단계는 JSON Schema 스펙 구현체를 마무리하고
백엔드 프레임워크를 작성해보고 싶네요.

현재 구직중이니 많은 관심 부탁드립니다.
읽어주셔서 감사합니다.

행복한 하루 되세요!

Read Entire Article