core
core copied to clipboard
TypeScript Migration Development
Proof of Concept (PoC): Encapsulation of Prop Metadata for CoreDivider Component
1. Introduction
This document provides a Proof of Concept (PoC) for encapsulating prop metadata in the CoreDivider component using CorePropDefinition and CorePropTypeDefinition. The approach enhances type safety, validation, and maintainability while ensuring a scalable architecture for managing component props.
2. Motivation
2.1 Problems with Traditional Prop Handling
- Prop validation is often handled inline within components, leading to duplication.
- Lack of strong typing can result in runtime errors and inconsistencies.
- Maintaining large-scale components with many props becomes difficult.
2.2 Advantages of the Proposed Approach
- Encapsulation of Prop Metadata: Using
CorePropDefinitionandCorePropTypeDefinitioncentralizes prop configurations, making the system reusable and maintainable. - Type Safety with TypeScript: Strongly typed definitions reduce errors and improve maintainability.
- Enhanced Validation Support: Built-in support for constraints like
validValues,default,constraints, andrequired. - Centralized Prop Configuration: Defining valid and invalid props separately improves modularity and avoids duplication.
3. Implementation
3.1 Core Divider Component (CoreDivider.tsx)
import React from "react";
import { NativeDivider } from "@wrappid/native";
import { sanitizeComponentProps } from "../../../utils/componentUtil";
import { validProps, invalidProps } from "./CoreDividerProps";
export interface CoreDividerProps {
absolute?: boolean;
component?: React.ElementType;
flexItem?: boolean;
light?: boolean;
orientation?: "horizontal" | "vertical";
textAlign?: "center" | "left" | "right";
variant?: "fullWidth" | "inset" | "middle";
leftInset?: boolean;
horizontalInset?: boolean;
bold?: boolean;
children?: React.ReactNode;
}
interface CoreDividerComponent extends React.FC<CoreDividerProps> {
validProps: typeof validProps;
invalidProps: typeof invalidProps;
}
const CoreDivider: CoreDividerComponent = (props) => {
const sanitizedProps = sanitizeComponentProps(CoreDivider, props) as CoreDividerProps;
const { children, ...restProps } = sanitizedProps;
return <NativeDivider {...restProps}>{children}</NativeDivider>;
};
CoreDivider.validProps = validProps;
CoreDivider.invalidProps = invalidProps;
export default CoreDivider;
3.2 Core Prop Definitions (CorePropDefinition.ts)
export class CorePropTypeDefinition {
default?: any;
type: string;
validValues?: any[];
constructor(type: string, defaultValue?: any, validValues?: any[]) {
this.type = type;
this.default = defaultValue;
this.validValues = validValues;
}
}
export class CorePropDefinition {
description?: string;
name: string;
types: CorePropTypeDefinition[];
constructor(name: string, types: CorePropTypeDefinition[], description?: string) {
this.name = name;
this.types = types;
this.description = description;
}
}
3.3 Centralized Prop Metadata (CoreDividerProps.ts)
import { CorePropDefinition, CorePropTypeDefinition } from "./CorePropDefinition";
export const validProps: CorePropDefinition[] = [
new CorePropDefinition("absolute", [new CorePropTypeDefinition("boolean", false, [true, false])], "Absolutely position the element."),
new CorePropDefinition("component", [new CorePropTypeDefinition("elementType")], "The component used for the root node."),
new CorePropDefinition("flexItem", [new CorePropTypeDefinition("boolean", false, [true, false])], "Ensures correct height in flex containers."),
new CorePropDefinition("light", [new CorePropTypeDefinition("boolean", false, [true, false])], "If true, applies a lighter color."),
new CorePropDefinition("orientation", [new CorePropTypeDefinition("string", "horizontal", ["horizontal", "vertical"])], "Determines component orientation."),
new CorePropDefinition("textAlign", [new CorePropTypeDefinition("string", "center", ["center", "left", "right"])], "Determines text alignment."),
new CorePropDefinition("variant", [new CorePropTypeDefinition("string", "fullWidth", ["fullWidth", "inset", "middle"])], "Defines the divider variant."),
new CorePropDefinition("leftInset", [new CorePropTypeDefinition("boolean", undefined, [true, false])]),
new CorePropDefinition("horizontalInset", [new CorePropTypeDefinition("boolean", undefined, [true, false])]),
new CorePropDefinition("bold", [new CorePropTypeDefinition("boolean", undefined, [true, false])]),
];
export const invalidProps: string[] = ["style", "theme"];
4. Key Benefits of This Approach
4.1 Encapsulation of Prop Metadata
- The
CorePropDefinitionandCorePropTypeDefinitionclasses provide a structured way to define and manage prop metadata. - Helps in reducing redundant prop definitions across different components.
4.2 Type Safety with TypeScript
- Strongly typed definitions ensure better tooling support and reduce runtime errors.
- The
React.ElementTypetype for thecomponentprop allows proper validation for custom component overrides.
4.3 Enhanced Validation Support
- Built-in support for
validValues,default,constraints, andrequiredimproves type checking. - The
deprecatedandreplacementfields allow future-proofing and better API evolution.
4.4 Centralized Prop Configuration
- Having a single
CoreDividerProps.tsfile for valid and invalid props enhances maintainability. - Helps in ensuring consistency across components while allowing easy modifications.
5. Conclusion
This PoC demonstrates how encapsulating prop metadata using TypeScript and object-oriented principles significantly improves maintainability, scalability, and type safety. The approach ensures that prop definitions are centralized, reusable, and easier to validate. This method provides a structured, future-proof way to manage props, making it ideal for large-scale component-driven applications.