ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Typed Component Props: Button Variant Renderer

TSX

Goal -- WPM

Ready
Exercise Algorithm Area
1interface BaseButtonProps {
2children: React.ReactNode;
3onClick: () => void;
4}
5
6type PrimaryButtonProps = BaseButtonProps & {
7variant: 'primary';
8icon?: 'star' | 'heart';
9};
10
11type SecondaryButtonProps = BaseButtonProps & {
12variant: 'secondary';
13icon?: 'gear' | 'user';
14};
15
16type DangerButtonProps = BaseButtonProps & {
17variant: 'danger';
18icon?: 'trash' | 'warning';
19};
20
21type ButtonProps = PrimaryButtonProps | SecondaryButtonProps | DangerButtonProps;
22
23function renderButton(props: ButtonProps): React.ReactElement {
24const { children, onClick, variant } = props;
25
26let buttonClass = `btn btn-${variant}`;
27let iconElement: React.ReactNode = null;
28
29// Handle icon rendering based on variant and specific icon
30if ('icon' in props && props.icon) {
31switch (variant) {
32case 'primary':
33iconElement = <span className={`icon icon-${props.icon}`}></span>;
34break;
35case 'secondary':
36iconElement = <i className={`fa fa-${props.icon}`}></i>;
37break;
38case 'danger':
39iconElement = <svg className={`svg-icon svg-${props.icon}`}></svg>;
40break;
41default:
42// This case should ideally not be reached due to TS types
43console.warn('Unknown button variant:', variant);
44break;
45}
46}
47
48return (
49<button className={buttonClass} onClick={onClick}>
50{iconElement}
51{children}
52</button>
53);
54}
Algorithm description viewbox

Typed Component Props: Button Variant Renderer

Algorithm description:

This function renders a button component with type-safe props. It uses a discriminated union for button variants and supports optional icons, ensuring that only valid icon types are associated with each variant. This pattern prevents runtime errors by enforcing type safety at compile time, making UI development more robust.

Algorithm explanation:

The `renderButton` function leverages TypeScript's discriminated unions to enforce type safety for component props. The `variant` property acts as the discriminant, allowing the type system to narrow down the possible `icon` types based on the chosen `variant`. This prevents developers from accidentally assigning an invalid icon to a button. The function checks for the presence of the `icon` property using `'icon' in props` before attempting to render it, handling the case where no icon is provided. The time complexity is O(1) as it involves a few property accesses and a switch statement. The space complexity is also O(1) as it only uses a few variables.

Pseudocode:

Define BaseButtonProps with children and onClick.
Define variant-specific props (Primary, Secondary, Danger) extending BaseButtonProps, each with a distinct 'variant' literal type and specific optional 'icon' types.
Combine these into a ButtonProps union type.
Create renderButton function accepting ButtonProps.
Destructure props: children, onClick, variant.
Initialize buttonClass based on variant.
Initialize iconElement to null.
If 'icon' property exists in props and is not null:
  Use a switch statement on 'variant' to determine the correct icon rendering logic.
  Assign the rendered icon element to iconElement.
Return a button element with the appropriate class, onClick handler, iconElement, and children.