A deque (pronounced deck, short for double-ended queue) is a linear collection that lets you add and remove items at both ends — the front and the back — each in constant time. That makes it a superset of two simpler structures: restrict it to one end and it behaves like a stack, add at one end and remove from the other and it behaves like a queue. Your deque() factory returns an object with eight methods that push, pop, and peek at each end, plus size and isEmpty. See double-ended queue for background.
function deque(): {
pushFront(value: unknown): void; // add value at the front
pushBack(value: unknown): void; // add value at the back
popFront(): unknown | undefined; // remove + return the front, or undefined if empty
popBack(): unknown | undefined; // remove + return the back, or undefined if empty
peekFront(): unknown | undefined; // read the front without removing, or undefined
peekBack(): unknown | undefined; // read the back without removing, or undefined
size(): number; // how many items are in the deque
isEmpty(): boolean; // true when the deque holds nothing
};
const d = deque();
d.pushBack('a');
d.pushBack('b');
d.pushBack('c');
d.popFront(); // 'a' — oldest out first, like a queue
d.popFront(); // 'b'
const d = deque();
d.pushFront(1);
d.pushFront(2);
d.pushFront(3); // front-to-back: [3, 2, 1]
d.peekFront(); // 3
d.popFront(); // 3 — newest out first, like a stack
const d = deque();
d.pushBack(1);
d.pushFront(0);
d.pushBack(2); // front-to-back: [0, 1, 2]
d.peekFront(); // 0
d.peekBack(); // 2
d.popBack(); // 2
d.size(); // 2
undefined — popFront, popBack, peekFront, and peekBack on an empty deque must not throw. Returning undefined is the spec.undefined, null, 0, and false. Don't filter or coerce; use size() or isEmpty() to tell an empty deque from a stored undefined.deque() twice gives you two separate deques; one's pushes don't appear in the other.