TypeScript中封装函数的类:实现正确类型与参数数量校验
Got it, let's build this function wrapper class exactly as you described—with parameter validation checks, rule count validation in the constructor, and wrapping the result in an RxJS Observable. Here's a clean vanilla JavaScript implementation that hits all your requirements:
Function Wrapper Class with Validation & RxJS Encapsulation
First, let's lay out the core class. We'll make sure the constructor enforces matching parameter and rule counts, then implement the call method to handle validation, execution, and result wrapping:
import { Observable } from 'rxjs'; class FunctionWrapper { constructor(targetFunction, validationRules) { // Validate rule count matches function parameter count upfront const expectedParamCount = targetFunction.length; if (validationRules.length !== expectedParamCount) { throw new Error(`Mismatch: Function expects ${expectedParamCount} parameters, but received ${validationRules.length} validation rules`); } this.targetFn = targetFunction; this.rules = validationRules; } call(...args) { // Step 1: Run all parameter validations this.rules.forEach((validateParam, index) => { const param = args[index]; if (!validateParam(param)) { throw new Error(`Parameter ${index} failed validation: ${JSON.stringify(param)}`); } }); // Step 2: Execute the original function const rawResult = this.targetFn(...args); // Step 3: Wrap result in an Observable return new Observable(subscriber => { subscriber.next(rawResult); subscriber.complete(); }); } }
Breakdown of Key Features:
- Constructor Safety Check: We use
targetFunction.lengthto get the number of named parameters the function expects, then compare it to the length of the validation rules array. If they don't match, we throw an immediate error to catch mismatches early. - Parameter Validation: The
callmethod loops through each validation rule and applies it to the corresponding argument. Any failed validation throws a descriptive error. - RxJS Encapsulation: After successful validation and function execution, we wrap the result in a basic Observable. If your target function returns a Promise, you can swap this out for
Observable.from(rawResult)to handle async results seamlessly.
Example Usage
Let's test this with a simple function and validation rules to see it in action:
// Sample target function: calculate area of a rectangle function calculateArea(width, height) { return width * height; } // Validation rules: both parameters must be positive numbers const areaValidationRules = [ (val) => typeof val === 'number' && val > 0, (val) => typeof val === 'number' && val > 0 ]; // Create wrapped instance const wrappedAreaCalc = new FunctionWrapper(calculateArea, areaValidationRules); // Use the wrapped function wrappedAreaCalc.call(5, 10).subscribe({ next: (area) => console.log('Calculated Area:', area), // Output: Calculated Area: 50 error: (err) => console.error('Validation Failed:', err) }); // Test invalid input wrappedAreaCalc.call(-5, 10).subscribe({ error: (err) => console.error('Validation Failed:', err) // Output: Validation Failed: Parameter 0 failed validation: -5 });
Optional Enhancements
If you want to extend this further, here are a few ideas:
- Add support for async validation rules (return Promises) by making the
callmethod async and awaiting validation checks. - Allow passing a
thiscontext to the target function via an optional second argument tocall. - Customize the error messages per validation rule instead of using a generic message.
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

