diff --git a/queue.js b/queue.js index 3f75cba..5be7fd4 100644 --- a/queue.js +++ b/queue.js @@ -7,14 +7,30 @@ export class QueueNode { } } +/** + * @template V + */ +export class QueueValue extends QueueNode { + /** + * @param {V} v + */ + constructor (v) { + super() + this.v = v + } +} + +/** + * @template {QueueNode} N + */ export class Queue { constructor () { /** - * @type {QueueNode | null} + * @type {N | null} */ this.start = null /** - * @type {QueueNode | null} + * @type {N | null} */ this.end = null } @@ -24,18 +40,20 @@ export class Queue { * @note The queue implementation is experimental and unfinished. * Don't use this in production yet. * - * @return {Queue} + * @template {QueueNode} N + * @return {Queue} */ export const create = () => new Queue() /** - * @param {Queue} queue + * @param {Queue} queue */ export const isEmpty = queue => queue.start === null /** - * @param {Queue} queue - * @param {QueueNode} n + * @template {Queue} Q + * @param {Q} queue + * @param {Q extends Queue ? N : never} n */ export const enqueue = (queue, n) => { if (queue.end !== null) { @@ -48,8 +66,9 @@ export const enqueue = (queue, n) => { } /** - * @param {Queue} queue - * @return {QueueNode | null} + * @template {QueueNode} N + * @param {Queue} queue + * @return {N | null} */ export const dequeue = queue => { const n = queue.start diff --git a/queue.test.js b/queue.test.js index 7b9db5c..76b1b30 100644 --- a/queue.test.js +++ b/queue.test.js @@ -1,43 +1,33 @@ import * as t from './testing.js' import * as queue from './queue.js' -class QueueItem extends queue.QueueNode { - /** - * @param {number} v - */ - constructor (v) { - super() - this.v = v - } -} - /** - * @param {t.TestCase} tc + * @param {t.TestCase} _tc */ -export const testEnqueueDequeue = tc => { +export const testEnqueueDequeue = _tc => { const N = 30 /** - * @type {queue.Queue} + * @type {queue.Queue>} */ const q = queue.create() t.assert(queue.isEmpty(q)) t.assert(queue.dequeue(q) === null) for (let i = 0; i < N; i++) { - queue.enqueue(q, new QueueItem(i)) + queue.enqueue(q, new queue.QueueValue(i)) t.assert(!queue.isEmpty(q)) } for (let i = 0; i < N; i++) { - const item = /** @type {QueueItem} */ (queue.dequeue(q)) + const item = queue.dequeue(q) t.assert(item !== null && item.v === i) } t.assert(queue.isEmpty(q)) t.assert(queue.dequeue(q) === null) for (let i = 0; i < N; i++) { - queue.enqueue(q, new QueueItem(i)) + queue.enqueue(q, new queue.QueueValue(i)) t.assert(!queue.isEmpty(q)) } for (let i = 0; i < N; i++) { - const item = /** @type {QueueItem} */ (queue.dequeue(q)) + const item = queue.dequeue(q) t.assert(item !== null && item.v === i) } t.assert(queue.isEmpty(q))