Category: type Since: 1.0.0 Tags: type, dimensions, target, scaling, exclusive, union
DimensionsTarget
Defines a target dimension using a single axis.
Usage
import type { DimensionsTarget } from "@petr-ptacek/js-core";
// Target specific width
const targetWidth: DimensionsTarget = { width: 800 };
// Target specific height
const targetHeight: DimensionsTarget = { height: 600 };
function scaleToTarget(original: Dimensions, target: DimensionsTarget): Dimensions {
if ("width" in target) {
const ratio = target.width / original.width;
return {
width: target.width,
height: Math.round(original.height * ratio),
};
} else {
const ratio = target.height / original.height;
return {
width: Math.round(original.width * ratio),
height: target.height,
};
}
}Why This Type Exists
Many scaling and resizing operations need to constrain only one dimension while calculating the other to preserve aspect ratio. DimensionsTarget enforces that exactly one dimension is specified, preventing invalid states and providing type safety for single-axis scaling operations.
Type Declaration
type DimensionsTarget = { width: number; height?: never } | { height: number; width?: never };When To Use
Use DimensionsTarget when:
- implementing aspect ratio preserving scaling
- constraining images to fit specific widths or heights
- building responsive image components
- creating thumbnail generation with size constraints
- working with scaling utilities that operate on single dimensions
// Responsive image sizing
function generateResponsiveSizes(original: Dimensions, targets: DimensionsTarget[]): Dimensions[] {
return targets.map((target) => scaleToTarget(original, target));
}
const breakpoints: DimensionsTarget[] = [
{ width: 320 }, // mobile
{ width: 768 }, // tablet
{ width: 1200 }, // desktop
{ height: 400 }, // specific height constraint
];
// Thumbnail generation
class ThumbnailGenerator {
generateThumbnail(image: Dimensions, constraint: DimensionsTarget): Dimensions {
if ("width" in constraint) {
return this.scaleByWidth(image, constraint.width);
} else {
return this.scaleByHeight(image, constraint.height);
}
}
private scaleByWidth(image: Dimensions, targetWidth: number): Dimensions {
const aspectRatio = image.height / image.width;
return {
width: targetWidth,
height: Math.round(targetWidth * aspectRatio),
};
}
private scaleByHeight(image: Dimensions, targetHeight: number): Dimensions {
const aspectRatio = image.width / image.height;
return {
width: Math.round(targetHeight * aspectRatio),
height: targetHeight,
};
}
}
// Form validation
function validateTarget(target: DimensionsTarget): boolean {
const hasWidth = "width" in target && typeof target.width === "number";
const hasHeight = "height" in target && typeof target.height === "number";
// TypeScript ensures exactly one is present, but runtime validation
return hasWidth !== hasHeight; // XOR: exactly one should be true
}When Not To Use
Avoid when:
- you need both dimensions simultaneously (use
Dimensionsdirectly) - working with proportional scaling that doesn't preserve aspect ratio
- you need multiple constraints or complex scaling logic
- the target can be optional or undefined (use optional
Dimensionsproperties)
Design Notes
This type uses discriminated unions with never types to enforce mutual exclusivity:
- Exclusive choice: Either
widthORheight, never both or neither - Type safety: TypeScript compiler prevents invalid combinations
- Runtime clarity: Clear intent about which dimension is being targeted
- Function overloads: Enables precise typing for scaling functions
The never type ensures that if one property is present, the other cannot be defined, providing compile-time guarantees about the object structure.
Summary
DimensionsTarget provides type-safe, mutually exclusive dimension targeting for aspect ratio preserving operations, ensuring exactly one axis is constrained while maintaining clear intent and preventing invalid scaling configurations.