Category: type Since: 1.0.0 Tags: type, function, identity, passthrough, neutral
Identity
Represents an identity function.
Usage
import type { Identity } from "@petr-ptacek/js-core";
// Basic identity functions
const identityNumber: Identity<number> = (value) => value;
const identityString: Identity<string> = (value) => value;
const identityUser: Identity<User> = (user) => user;
// Default projections
function processItems<T, U>(items: T[], projection: (item: T) => U = identityNumber as any): U[] {
return items.map(projection);
}
// Passthrough in pipelines
function createPipeline<T>() {
const transformers: Array<(value: T) => T> = [];
return {
add(transformer: Identity<T> = (x) => x) {
transformers.push(transformer);
return this;
},
execute(value: T): T {
return transformers.reduce((acc, fn) => fn(acc), value);
},
};
}
// Usage examples
const numberPipeline = createPipeline<number>()
.add((x) => x * 2)
.add((x) => x) // identity - no transformation
.add((x) => x + 1);
const result = numberPipeline.execute(5); // ((5 * 2) * 1) + 1 = 11Why This Type Exists
Identity functions are fundamental in functional programming as neutral elements for composition and default values for optional transformations. Identity<T> provides a clear, typed representation for functions that pass values through unchanged, commonly used in higher-order functions, pipelines, and as default parameters.
Type Declaration
type Identity<T> = (value: T) => T;Type Parameters
<T>: The type of both the input and output value (they are the same).
When To Use
Use Identity<T> when:
- providing default transformation functions in utilities
- building functional pipelines that may skip certain steps
- creating no-op transformations in conditional logic
- implementing neutral elements in composition patterns
- working with higher-order functions that need passthrough options
// Conditional transformation
function conditionalTransform<T>(value: T, condition: boolean, transform: Identity<T>): T {
return condition ? transform(value) : value;
}
// Utility with optional transformation
function mapWithOptionalTransform<T>(array: T[], transform?: Identity<T>): T[] {
const fn = transform || ((x: T) => x);
return array.map(fn);
}
// Composition with neutral element
function compose<T>(...fns: Identity<T>[]): Identity<T> {
return (value: T) => fns.reduce((acc, fn) => fn(acc), value);
}
const composed = compose<number>(
(x) => x * 2,
(x) => x, // identity - neutral element
(x) => x + 1
);When Not To Use
Avoid when:
- you need transformation between different types (use
ProjectionFn<T, U>) - the function should never be called (use
neveror omit the parameter) - you need complex logic beyond simple passthrough
- performance is critical and function call overhead matters
Design Notes
Identity functions serve as:
- Neutral elements: Don't change values in composition
- Default parameters: Safe fallback for optional transformations
- Type preservation: Maintain input type as output type
- Functional purity: No side effects, referentially transparent
The type is particularly useful in functional programming patterns and generic utilities.
Summary
Identity<T> provides a clear type for functions that return input values unchanged, serving as neutral elements in functional composition and default transformations in higher-order utilities.