Say your order tracker passes status codes as plain strings. A typo like "SHIPED" compiles without a peep.
To use TypeScript enums with functions, type each parameter and return value as the enum, like status: OrderStatus. Then only real members get through.
In this tutorial, I’ll build a small order-status module that shows how to use TypeScript enums with functions: typed parameters, an exhaustive switch, a fee lookup, helper methods and input checks.
Here’s what we’re building. It rejects an unknown status and prints a fee for the rest:

LOST.I compiled each file with --strict and ran it on TypeScript 7.0.2 and Node.js v22.22.2.
Before You Start: the OrderStatus enum
You only need TypeScript and Node.js. Every file below starts with this string enum, so paste it at the top of each one:
enum OrderStatus {
Pending = "PENDING", Shipped = "SHIPPED",
Delivered = "DELIVERED", Cancelled = "CANCELLED",
}
String values read well in logs and JSON. The TypeScript enums guide covers numeric enums too.
Step 1: Type a function parameter with the enum
Add a function that takes and returns an OrderStatus:
function nextStatus(status: OrderStatus): OrderStatus {
if (status === OrderStatus.Pending) return OrderStatus.Shipped;
if (status === OrderStatus.Shipped) return OrderStatus.Delivered;
return status; // Delivered and Cancelled stay put
}
console.log(nextStatus(OrderStatus.Pending));
console.log(nextStatus(OrderStatus.Shipped));
console.log(nextStatus(OrderStatus.Cancelled));
Output:
SHIPPED
DELIVERED
CANCELLED

OrderStatus member.Checkpoint: you see SHIPPED, DELIVERED and CANCELLED.
Step 2: Make the enum switch exhaustive
The never line in default makes the compiler flag any member your switch forgets. I left out Cancelled on purpose:
function describe(status: OrderStatus): string {
switch (status) {
case OrderStatus.Pending: return "Waiting to ship";
case OrderStatus.Shipped: return "On the truck";
case OrderStatus.Delivered: return "At the door";
default: const missed: never = status; return missed;
}
}
Compiler output:
status_switch.ts(11,20): error TS2322: Type 'OrderStatus.Cancelled' is not assignable to type 'never'.

Cancelled has no case.Add the missing case above default:
case OrderStatus.Cancelled: return "Refund issued";
Checkpoint: the build passes and all four labels print.
More patterns: switch statements with TypeScript enums.
Step 3: Look up enum values with a Record
Fees don’t need a switch. A Record<OrderStatus, number> maps every member to a number:
const fee: Record<OrderStatus, number> = {
PENDING: 0, SHIPPED: 7.99, DELIVERED: 7.99, CANCELLED: 0,
};
const total = (subtotal: number, status: OrderStatus): string =>
`$${(subtotal + fee[status]).toFixed(2)}`;
console.log(total(42.5, OrderStatus.Shipped));
console.log(total(42.5, OrderStatus.Cancelled));
Output:
$50.49
$42.50

$50.49; cancelled stays $42.50.Checkpoint: two totals print. Drop CANCELLED and tsc fails with TS2741, so no member goes without a fee.
It works for labels too; see TypeScript enums as object keys.
Step 4: Attach functions to the enum with a namespace
Want OrderStatus.isFinal() like a method? A namespace with the same name merges into the enum:
namespace OrderStatus {
export function isFinal(s: OrderStatus): boolean {
return s === OrderStatus.Delivered || s === OrderStatus.Cancelled;
}
}
console.log(OrderStatus.isFinal(OrderStatus.Shipped));
console.log(OrderStatus.isFinal(OrderStatus.Cancelled));
console.log(Object.keys(OrderStatus));
Output:
false
true
[ 'Pending', 'Shipped', 'Delivered', 'Cancelled', 'isFinal' ]

isFinal now shows up in Object.keys() too.Important: filter out functions before you loop over the members.
A class can hold the helpers instead; see TypeScript enums in classes.
Test the enum functions on raw input
CSV and API data arrives as plain strings, so the finished file checks each one with a type guard:
const fee: Record<OrderStatus, number> =
{ PENDING: 0, SHIPPED: 7.99, DELIVERED: 7.99, CANCELLED: 0 };
const isStatus = (v: string): v is OrderStatus =>
Object.values<string>(OrderStatus).includes(v);
for (const raw of ["SHIPPED", "PENDING", "LOST", "DELIVERED"]) {
console.log(isStatus(raw)
? `${raw}: fee $${fee[raw].toFixed(2)}`
: `${raw}: rejected, not an OrderStatus`);
}
Output:
SHIPPED: fee $7.99
PENDING: fee $0.00
LOST: rejected, not an OrderStatus
DELIVERED: fee $7.99
v is OrderStatus narrows raw in the true branch, so fee[raw] compiles, and LOST gets rejected.
Other options: check if a value exists in a TypeScript enum.
How do you fix enum function errors?
The one I hit most: ship("SHIPPED") on a status: OrderStatus parameter fails with TS2345, because a string literal isn’t assignable to a string enum.
Pass OrderStatus.Shipped, or validate outside data first; see converting a string to an enum in TypeScript.
Where to Take It Next with enum functions
- Fill a drop-down via an enum-to-array conversion.
- Combine statuses into one value with enums that hold multiple values.
- Weigh enums vs string literal unions.
Still on enums? These go deeper:
- Iterate over enums in TypeScript
- Get an enum key by value in TypeScript
- Reverse mapping in TypeScript enums
- Get all enum values in TypeScript
Frequently asked questions
Can a TypeScript function take an enum as a parameter?
Yes. Type it as status: OrderStatus; only members are accepted.
Can a function return an enum value?
Yes. Set the return type to the enum, as nextStatus() does.
How do I add a method to a TypeScript enum?
Merge a same-name namespace and export functions from it.
How do I write a function that accepts any string enum?
Use a generic, <T extends Record<string, string>>(e: T), and pass the enum object.
Why does passing “SHIPPED” fail for a string enum?
A string literal isn’t assignable to a string enum (TS2345). Pass the member instead.