Skip to main content

when()

when<T, Result>(value, predicate, transformation): T | Result

Applies a transformation to a value when a predicate is true.

πŸ’Ž Why is this a Hidden Gem?

A functional alternative to ternary operators. Applies a transformation only if the predicate is true.

note

Logical opposite of unless.


Type Parameters​

T: T​

The type of the input value.

Result: Result​

The type of the transformed value.


Parameters​

value: T​

The value to potentially transform.

predicate: (value) => boolean​

Function that returns true to apply transformation.

transformation: (value) => Result​

The function to apply when predicate is true.


Returns: T | Result​

The transformed value if predicate is true, otherwise the original value.


See Also​

unless


Since​

2.0.0


Also known as​

when (Remeda, Ramda) · ❌ (Lodash, es-toolkit, Radashi, Effect, Modern Dash, Antfu)


Example​

when(4, (n) => n % 2 === 0, (n) => n * 2);
// => 8 (4 is even, predicate true, transforms)

when(3, (n) => n % 2 === 0, (n) => n * 2);
// => 3 (3 is odd, predicate false, skips)

when('hello world', (s) => s.length > 10, (s) => s.slice(0, 10) + '...');
// => 'hello worl...'

How it works?​

Applies a transformation only when the predicate returns true. If predicate is false, returns the original value unchanged.

when vs unless​

whenunless
Transforms ifpredicate = truepredicate = false
Skips ifpredicate = falsepredicate = true

Use Cases​

Truncate text only if too long πŸ“Œβ€‹

Add ellipsis only when text exceeds maximum length. Essential for UI text display and responsive design.

const truncate = (text, max) =>
when(text, (t) => t.length > max, (t) => t.slice(0, max) + "...");

truncate("Hello World", 5); // "Hello..."
truncate("Hi", 5); // "Hi"

Apply discount only for members πŸ“Œβ€‹

Calculate discounted price only when user has membership. Critical for e-commerce and pricing logic.

const getPrice = (price, user) =>
when(price, () => user.isMember, (p) => p * 0.9);

Flip layout properties for RTL mode​

Swap left/right properties when the document direction is RTL. Essential for design systems supporting bidirectional text layouts.

const getPosition = (baseLeft: number, isRTL: boolean) =>
when({ left: baseLeft, right: "auto" }, () => isRTL, (pos) => ({
left: "auto",
right: pos.left,
}));

getPosition(100, false); // => { left: 100, right: "auto" }
getPosition(100, true); // => { left: "auto", right: 100 }

Apply reduced motion styles conditionally​

Disable or simplify animations when the user prefers reduced motion. Critical for accessible design systems respecting user preferences.

const animationConfig = (duration: number, easing: string) =>
when(
{ duration, easing, enabled: true },
() => window.matchMedia("(prefers-reduced-motion: reduce)").matches,
(config) => ({ ...config, duration: 0, enabled: false })
);

animationConfig(300, "ease-out");
// Reduced motion ON: { duration: 0, easing: "ease-out", enabled: false }
// Reduced motion OFF: { duration: 300, easing: "ease-out", enabled: true }

Collapse panel content when screen is small​

Automatically collapse sidebar or panel content on small screens. Perfect for responsive dashboards and adaptive layouts.

const panelState = (width: number) =>
when({ expanded: true, width }, (s) => s.width < 768, (s) => ({ ...s, expanded: false }));

panelState(1024); // => { expanded: true, width: 1024 }
panelState(640); // => { expanded: false, width: 640 }

Add accessibility label only when icon-only​

Add an aria-label only when a button has no visible text. Essential for accessible icon buttons in design systems.

const buttonProps = (label: string, hasText: boolean) =>
when({ label }, () => !hasText, (props) => ({ ...props, "aria-label": props.label }));

buttonProps("Close", false); // => { label: "Close", "aria-label": "Close" }
buttonProps("Close", true); // => { label: "Close" }