Bộ triển khai JSON Schema dựa trên TypeScript và bộ công cụ phát triển
(github.com/imhonglu)Đây là một dự án được bắt đầu với mong muốn “hãy tự tạo ra một thư viện an toàn kiểu đúng gu của mình”.
Dự án này khởi đầu từ một bộ triển khai JSON Schema an toàn kiểu và sau đó tự nhiên mở rộng thành nhiều công cụ khác nhau cần thiết trong quá trình phát triển.
Hiện tại, tôi tạm khép lại giai đoạn đầu tiên để chuẩn bị cho việc tìm việc.
Nguyên tắc dự án
Dự án được phát triển với việc tuân thủ các nguyên tắc cốt lõi sau:
- Tận dụng hệ thống kiểu nghiêm ngặt
- Duy trì tối thiểu các phụ thuộc bên ngoài
- Thiết kế hệ thống kiểu có thể tái sử dụng
- Tài liệu hóa API
- Duy trì độ bao phủ kiểm thử cao
- Triển khai hoàn toàn bằng TypeScript thuần
Thư viện
@imhonglu/json-schema
Đây là bộ triển khai TypeScript tuân thủ đặc tả JSON Schema draft 2020-12.
- Kho mã: https://github.com/imhonglu/new-wheels/…
- Được kiểm chứng thông qua
JSON-Schema-Test-Suite - Kiểu của các keyword có thể dùng sẽ được tự động suy luận theo định nghĩa schema.
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
Đây là dự án được bắt đầu để triển khai keyword format của JSON Schema.
- Kho mã: https://github.com/imhonglu/new-wheels/…
- Triển khai dựa trên đặc tả RFC
- Kiểm chứng dựa trên
JSON-Schema-Test-Suite - Cung cấp giao diện tương tự API
JSONgốc
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
Đây là regex builder được tạo ra để cải thiện khả năng đọc của biểu thức chính quy trong quá trình triển khai ngữ pháp ABNF của đặc tả RFC.
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
Đây là thư viện type guard được tạo ra để cải thiện tính dễ đọc của type guard.
- Kho mã: https://github.com/imhonglu/new-wheels/…
- Triển khai dựa trên Proxy để giảm thiểu overhead
- Cung cấp 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
Đây là thư viện wrapper an toàn kiểu cho Object API gốc. Nó cung cấp các kiểu gần với hành vi gốc.
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
Đây là tập hợp các utility type và utility function đang được sử dụng bên trong dự án.
import type { Fn } from '@imhonglu/toolkit';
// Cung cấp type alias cho kiểu hàm '(...args: any[]) => any'.
Fn.Callable // (...args: any[]) => any
// Có thể chỉ định riêng kiểu tham số thông qua generic.
Fn.Callable<{ args: [number, number] }> // (...args: [number, number]) => any
// Có thể chỉ định riêng kiểu trả về thông qua generic.
Fn.Callable<{ return: string }> // (...args: any[]) => string
// Có thể đồng thời chỉ định cả kiểu tham số và kiểu trả về thông qua generic.
Fn.Callable<{ args: [number, number], return: string }> // (...args: [number, number]) => string
Kế hoạch sắp tới và tìm việc
Bước tiếp theo của dự án đang thực hiện là hoàn thiện bộ triển khai đặc tả JSON Schema
và tôi cũng muốn thử viết một backend framework.
Hiện tôi đang tìm việc, rất mong nhận được sự quan tâm từ mọi người.
Xin cảm ơn vì đã đọc.
Chúc bạn một ngày vui vẻ!
2 bình luận
Bên này có một lựa chọn rất nổi bật là zod nên trong sản phẩm chúng tôi đang dùng cái đó, nhưng cũng khá thú vị đấy
Các dự án có sẵn như ajv, typia, zod cũng là những dự án mà tôi đang theo dõi với sự quan tâm lớn.
Trường hợp
safeParsecủa@imhonglu/formatcũng là một tính năng chịu ảnh hưởng từ API của zod.Cảm ơn bạn đã quan tâm!