TypeScript-basierte JSON-Schema-Implementierung und Sammlung von Entwicklungswerkzeugen
(github.com/imhonglu)Dieses Projekt begann mit dem Gedanken: „Lass uns eine typsichere Bibliothek nach meinem Geschmack bauen.“
Ausgehend von einer typsicheren JSON-Schema-Implementierung hat es sich im Lauf der Entwicklung ganz natürlich zu einer Vielzahl von Werkzeugen erweitert, die im Entwicklungsprozess benötigt werden.
Vorerst habe ich im Zuge meiner Jobsuche einen ersten Abschluss gesetzt.
Projektprinzipien
Die Entwicklung folgte dabei den folgenden Kernprinzipien:
- Nutzung eines strengen Typsystems
- Möglichst geringe externe Abhängigkeiten
- Entwurf eines wiederverwendbaren Typsystems
- API-Dokumentation
- Hohe Testabdeckung
- Reine TypeScript-Implementierung
Bibliotheken
@imhonglu/json-schema
Eine TypeScript-Implementierung, die der Spezifikation des JSON Schema Draft 2020-12 entspricht.
- Repository: https://github.com/imhonglu/new-wheels/…
- Verifizierung mit der
JSON-Schema-Test-Suite - Die Typen der je nach Schemadefinition verfügbaren Keywords werden automatisch abgeleitet.
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
Dieses Projekt wurde gestartet, um das format-Keyword von JSON Schema zu implementieren.
- Repository: https://github.com/imhonglu/new-wheels/…
- Implementierung auf Basis der RFC-Spezifikationen
- Verifizierung auf Basis der
JSON-Schema-Test-Suite - Bietet eine Schnittstelle ähnlich der nativen
JSON-API
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
Ein Regex-Builder, der während der Implementierung der ABNF-Grammatik aus den RFC-Spezifikationen entwickelt wurde, um die Lesbarkeit regulärer Ausdrücke zu verbessern.
- Repository: https://github.com/imhonglu/new-wheels/…
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
Eine Type-Guard-Bibliothek, die entwickelt wurde, um die Lesbarkeit von Type Guards zu verbessern.
- Repository: https://github.com/imhonglu/new-wheels/…
- Proxy-basierte Implementierung zur Minimierung des Overheads
- Bietet das Keyword
not
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
Eine typsichere Wrapper-Bibliothek für die native Object-API. Sie bietet Typen, die dem nativen Verhalten nahekommen.
- Repository: https://github.com/imhonglu/new-wheels/…
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
Eine Sammlung von Utility-Typen und Utility-Funktionen, die intern im Projekt verwendet werden.
- Repository: https://github.com/imhonglu/new-wheels/…
import type { Fn } from '@imhonglu/toolkit';
// Bietet einen Typalias für den Funktionstyp '(...args: any[]) => any'.
Fn.Callable // (...args: any[]) => any
// Über Generics kann nur der Argumenttyp definiert werden.
Fn.Callable<{ args: [number, number] }> // (...args: [number, number]) => any
// Über Generics kann nur der Rückgabetyp definiert werden.
Fn.Callable<{ return: string }> // (...args: any[]) => string
// Über Generics können sowohl Argumenttyp als auch Rückgabetyp definiert werden.
Fn.Callable<{ args: [number, number], return: string }> // (...args: [number, number]) => string
Zukünftige Pläne und Jobsuche
Der nächste Schritt für das laufende Projekt ist, die Implementierung der JSON-Schema-Spezifikation abzuschließen
und mich an einem Backend-Framework zu versuchen.
Ich bin derzeit auf Jobsuche und freue mich über Ihr Interesse.
Vielen Dank fürs Lesen.
Ich wünsche Ihnen einen schönen Tag!
2 Kommentare
In diesem Bereich gibt es mit zod bereits etwas Herausragendes, deshalb verwenden wir das im Produkt, aber es ist interessant.
Ich verfolge auch etablierte Projekte wie
ajv,typiaundzodmit großem Interesse.Auch
safeParsevon@imhonglu/formatist eine Funktion, die von der zod-API beeinflusst wurde.Vielen Dank für Ihr Interesse!