Rumah > Artikel > hujung hadapan web > Pengecualian Masa Kompilasi Kaya dalam TypeScript Menggunakan Jenis Tidak Boleh Dibina
Sistem jenis TypeScript berkuasa, tetapi mesej ralatnya kadangkala boleh menjadi samar dan sukar difahami. Dalam artikel ini, kami akan meneroka corak yang menggunakan jenis yang tidak boleh dibina untuk mencipta pengecualian masa kompilasi yang jelas dan deskriptif. Pendekatan ini membantu mengelakkan ralat masa jalan dengan menjadikan keadaan tidak sah tidak dapat diwakili dengan mesej ralat yang berguna.
Pertama, mari kita pecahkan corak teras:
// Create a unique symbol for our type exception declare const TypeException: unique symbol; // Basic type definitions type Struct = Record<string, any>; type Funct<T, R> = (arg: T) => R; type Types<T> = keyof T & string; type Sanitize<T> = T extends string ? T : never; // The core pattern for type-level exceptions export type Unbox<T extends Struct> = { [Type in Types<T>]: T[Type] extends Funct<any, infer Ret> ? (arg: Ret) => any : T[Type] extends Struct ? { [TypeException]: `Variant <${Sanitize<Type>}> is of type <Union>. Migrate logic to <None> variant to capture <${Sanitize<Type>}> types.`; } : (value: T[Type]) => any; };
Berikut ialah contoh yang menunjukkan cara menggunakan corak ini dengan jenis varian:
type DataVariant = | { type: 'text'; content: string } | { type: 'number'; value: number } | { type: 'complex'; nested: { data: string } }; type VariantHandler = Unbox<{ text: (content: string) => void; number: (value: number) => void; complex: { // This will trigger our custom error [TypeException]: `Variant <complex> is of type <Union>. Migrate logic to <None> variant to capture <complex> types.` }; }>; // This will show our custom error at compile time const invalidHandler: VariantHandler = { text: (content) => console.log(content), number: (value) => console.log(value), complex: (nested) => console.log(nested) // Error: Type has unconstructable signature };
Berikut ialah contoh yang lebih kompleks yang menunjukkan cara menggunakan corak dengan jenis rekursif:
type TreeNode<T> = { value: T; children?: TreeNode<T>[]; }; type TreeHandler<T> = Unbox<{ leaf: (value: T) => void; node: TreeNode<T> extends Struct ? { [TypeException]: `Cannot directly handle node type. Use leaf handler for individual values.`; } : never; }>; // Usage example - will show custom error const invalidTreeHandler: TreeHandler<string> = { leaf: (value) => console.log(value), node: (node) => console.log(node) // Error: Cannot directly handle node type };
Begini cara kita boleh menggunakan corak untuk menguatkuasakan peralihan keadaan jenis yang sah:
type LoadingState<T> = { idle: null; loading: null; error: Error; success: T; }; type StateHandler<T> = Unbox<{ idle: () => void; loading: () => void; error: (error: Error) => void; success: (data: T) => void; // Prevent direct access to state object state: LoadingState<T> extends Struct ? { [TypeException]: `Cannot access state directly. Use individual handlers for each state.`; } : never; }>; // This will trigger our custom error const invalidStateHandler: StateHandler<string> = { idle: () => {}, loading: () => {}, error: (e) => console.error(e), success: (data) => console.log(data), state: (state) => {} // Error: Cannot access state directly };
Corak ini amat berguna apabila:
Mari kita pecahkan cara corak berfungsi secara dalaman:
// Create a unique symbol for our type exception declare const TypeException: unique symbol; // Basic type definitions type Struct = Record<string, any>; type Funct<T, R> = (arg: T) => R; type Types<T> = keyof T & string; type Sanitize<T> = T extends string ? T : never; // The core pattern for type-level exceptions export type Unbox<T extends Struct> = { [Type in Types<T>]: T[Type] extends Funct<any, infer Ret> ? (arg: Ret) => any : T[Type] extends Struct ? { [TypeException]: `Variant <${Sanitize<Type>}> is of type <Union>. Migrate logic to <None> variant to capture <${Sanitize<Type>}> types.`; } : (value: T[Type]) => any; };
Menggunakan jenis yang tidak boleh dibina dengan mesej ralat tersuai ialah corak yang berkuasa untuk mencipta kekangan jenis pendokumentasian sendiri. Ia memanfaatkan sistem jenis TypeScript untuk memberikan panduan yang jelas pada masa penyusunan, membantu pembangun menangkap dan membetulkan isu sebelum ia menjadi masalah masa jalan.
Corak ini amat berharga apabila membina sistem jenis kompleks di mana kombinasi tertentu seharusnya tidak sah. Dengan menjadikan keadaan tidak sah tidak dapat diwakili dan memberikan mesej ralat yang jelas, kami boleh mencipta kod TypeScript yang lebih boleh diselenggara dan mesra pembangun.
Atas ialah kandungan terperinci Pengecualian Masa Kompilasi Kaya dalam TypeScript Menggunakan Jenis Tidak Boleh Dibina. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!