events
Большая часть основного API Node.js построена на идиоматичной асинхронной событийно-ориентированной архитектуре, в которой объекты определённых типов (называемые «эмиттерами») генерируют именованные события, вызывающие Function объекты («обработчики»).
Например: объект net.Server генерирует событие каждый раз, когда к нему подключается узел; объект fs.ReadStream генерирует событие при открытии файла; объект stream генерирует событие каждый раз, когда данные становятся доступны для чтения.
Все объекты, генерирующие события, являются экземплярами класса EventEmitter. Эти объекты предоставляют функцию eventEmitter.on(), которая позволяет привязать одну или несколько функций к именованным событиям, генерируемым объектом. Обычно имена событий представляют собой строки в стиле camelCase, но можно использовать любой допустимый ключ свойства JavaScript.
Когда объект EventEmitter генерирует событие, все функции, привязанные к этому событию, вызываются синхронно. Любые значения, возвращённые вызванными обработчиками, игнорируются и отбрасываются.
В следующем примере показан простой экземпляр EventEmitter с одним обработчиком. Метод eventEmitter.on() используется для регистрации обработчиков, а метод eventEmitter.emit() — для вызова события.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');
Использование в Deno
import * as mod from "node:events";
класс EventEmitter.EventEmitterAsyncResource
Использование в Deno
import { EventEmitter } from "node:events";
Интегрирует EventEmitter с AsyncResource для EventEmitter, которым требуется ручное отслеживание асинхронных операций. В частности, все события, генерируемые экземплярами events.EventEmitterAsyncResource, будут выполняться в рамках его async context.
import { EventEmitterAsyncResource, EventEmitter } from 'node:events';
import { notStrictEqual, strictEqual } from 'node:assert';
import { executionAsyncId, triggerAsyncId } from 'node:async_hooks';
// Async tracking tooling will identify this as 'Q'.
const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
// 'foo' listeners will run in the EventEmitters async context.
ee1.on('foo', () => {
strictEqual(executionAsyncId(), ee1.asyncId);
strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
});
const ee2 = new EventEmitter();
// 'foo' listeners on ordinary EventEmitters that do not track async
// context, however, run in the same async context as the emit().
ee2.on('foo', () => {
notStrictEqual(executionAsyncId(), ee2.asyncId);
notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId);
});
Promise.resolve().then(() => {
ee1.emit('foo');
ee2.emit('foo');
});
Класс EventEmitterAsyncResource имеет те же методы и принимает те же параметры, что и сами EventEmitter и AsyncResource.
Конструкторы
EventEmitterAsyncResource(options?: EventEmitterAsyncResourceOptions) Свойства
asyncId: number Уникальный asyncId, присвоенный ресурсу.
asyncResource: EventEmitterReferencingAsyncResource Возвращаемый объект AsyncResource имеет дополнительное свойство eventEmitter, предоставляющее ссылку на этот EventEmitterAsyncResource.
triggerAsyncId: number То же значение triggerAsyncId, которое передаётся конструктору AsyncResource.
Методы
emitDestroy(): void Вызывает все хуки destroy. Этот метод следует вызывать только один раз. При повторном вызове будет выброшена ошибка. Его необходимо вызывать вручную. Если ресурс будет удалён сборщиком мусора, хуки destroy никогда не будут вызваны.
класс EventEmitter
Использование в Deno
import { EventEmitter } from "node:events";
Класс EventEmitter определён и предоставлен модулем node:events:
import { EventEmitter } from 'node:events';
Все EventEmitters генерируют событие 'newListener' при добавлении новых слушателей и 'removeListener' при удалении существующих слушателей.
Поддерживается следующий параметр:
Конструкторы
EventEmitter(options?: EventEmitterOptions) Параметры типа
T extends EventMap<T> = DefaultEventMap Методы
[EventEmitter.captureRejectionSymbol]<K>(): void Статические свойства
captureRejectionSymbol: unique symbol Значение: Symbol.for('nodejs.rejection')
См. инструкции по созданию пользовательского rejection handler.
captureRejections: boolean Значение: логическое значение
Изменяет параметр captureRejections по умолчанию для всех новых объектов EventEmitter.
defaultMaxListeners: number По умолчанию для любого отдельного события можно зарегистрировать не более 10 слушателей. Этот лимит можно изменить для отдельных экземпляров EventEmitter с помощью метода emitter.setMaxListeners(n). Чтобы изменить значение по умолчанию для всех экземпляров EventEmitter, можно использовать свойство events.defaultMaxListeners. Если это значение не является положительным числом, возникает исключение RangeError.
Будьте осторожны при изменении events.defaultMaxListeners, поскольку это изменение затрагивает все экземпляры EventEmitter, в том числе созданные до внесения изменения. Однако вызов emitter.setMaxListeners(n) по-прежнему имеет приоритет над events.defaultMaxListeners.
Это не жёсткий лимит. Экземпляр EventEmitter позволит добавить больше слушателей, но выведет в stderr предупреждение с трассировкой о том, что обнаружена «возможная утечка памяти EventEmitter». Для любого отдельного EventEmitter методы emitter.getMaxListeners() и emitter.setMaxListeners() можно использовать, чтобы временно избежать этого предупреждения:
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once('event', () => {
// do stuff
emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});
Флаг командной строки --trace-warnings можно использовать для отображения трассировки стека таких предупреждений.
Сгенерированное предупреждение можно проверить с помощью process.on('warning'); оно будет содержать дополнительные свойства emitter, type и count, которые указывают соответственно на экземпляр эмиттера событий, имя события и количество подключённых слушателей. Свойству name присваивается значение 'MaxListenersExceededWarning'.
errorMonitor: unique symbol Этот символ следует использовать для установки слушателя, который только отслеживает события 'error'. Слушатели, установленные с помощью этого символа, вызываются до обычных слушателей 'error'.
Установка слушателя с помощью этого символа не меняет поведение при возникновении события 'error'. Поэтому процесс по-прежнему завершится аварийно, если обычный слушатель 'error' не установлен.
Статические методы
addAbortListener(
signal: AbortSignal,
resource: (event: Event) => void,
): Disposable Однократно прослушивает событие abort у переданного объекта signal.
Прослушивание события abort у сигналов отмены небезопасно и может привести к утечкам ресурсов, поскольку другая сторона, использующая этот сигнал, может вызвать e.stopImmediatePropagation(). К сожалению, Node.js не может изменить это поведение, поскольку оно нарушило бы веб-стандарт. Кроме того, в исходном API легко забыть удалить слушатели.
Этот API позволяет безопасно использовать AbortSignals в API Node.js, решая обе эти проблемы: событие прослушивается так, что stopImmediatePropagation не препятствует вызову слушателя.
Возвращает объект с возможностью освобождения ресурсов, чтобы упростить отмену подписки.
import { addAbortListener } from 'node:events';
function example(signal) {
let disposable;
try {
signal.addEventListener('abort', (e) => e.stopImmediatePropagation());
disposable = addAbortListener(signal, (e) => {
// Do something when signal is aborted.
});
} finally {
disposable?.[Symbol.dispose]();
}
}
getEventListeners(
emitter: EventTarget | EventEmitter,
name: string | symbol,
): Function[] Возвращает копию массива слушателей события с именем eventName.
Для EventEmitters это работает точно так же, как вызов .listeners у эмиттера.
Для EventTargets это единственный способ получить слушателей события для целевого объекта событий. Это полезно для отладки и диагностики.
import { getEventListeners, EventEmitter } from 'node:events';
{
const ee = new EventEmitter();
const listener = () => console.log('Events are fun');
ee.on('foo', listener);
console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ]
}
{
const et = new EventTarget();
const listener = () => console.log('Events are fun');
et.addEventListener('foo', listener);
console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ]
}
getMaxListeners(emitter: EventTarget | EventEmitter): number Возвращает текущее максимальное количество слушателей.
Для EventEmitters это работает точно так же, как вызов .getMaxListeners у эмиттера.
Для EventTargets это единственный способ получить максимальное число слушателей событий для целевого объекта событий. Если количество обработчиков событий у одного EventTarget превышает установленный максимум, EventTarget выведет предупреждение.
import { getMaxListeners, setMaxListeners, EventEmitter } from 'node:events';
{
const ee = new EventEmitter();
console.log(getMaxListeners(ee)); // 10
setMaxListeners(11, ee);
console.log(getMaxListeners(ee)); // 11
}
{
const et = new EventTarget();
console.log(getMaxListeners(et)); // 10
setMaxListeners(11, et);
console.log(getMaxListeners(et)); // 11
}
listenerCount(
emitter: EventEmitter,
eventName: string | symbol,
): number Метод класса, возвращающий количество слушателей для указанного eventName, зарегистрированных у указанного emitter.
import { EventEmitter, listenerCount } from 'node:events';
const myEmitter = new EventEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(listenerCount(myEmitter, 'event'));
// Prints: 2
on(): AsyncIterator<any[]> import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
// Emit later on
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo')) {
// The execution of this inner block is synchronous and it
// processes one event at a time (even with await). Do not use
// if concurrent execution is required.
console.log(event); // prints ['bar'] [42]
}
// Unreachable here
Возвращает AsyncIterator, который перебирает события eventName. Если EventEmitter генерирует событие 'error', возникает исключение. При выходе из цикла все слушатели удаляются. value, возвращаемый на каждой итерации, представляет собой массив, состоящий из аргументов сгенерированного события.
Для отмены ожидания событий можно использовать AbortSignal:
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ac = new AbortController();
(async () => {
const ee = new EventEmitter();
// Emit later on
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
});
for await (const event of on(ee, 'foo', { signal: ac.signal })) {
// The execution of this inner block is synchronous and it
// processes one event at a time (even with await). Do not use
// if concurrent execution is required.
console.log(event); // prints ['bar'] [42]
}
// Unreachable here
})();
process.nextTick(() => ac.abort());
Используйте параметр close, чтобы указать массив имён событий, при возникновении которых перебор завершится:
import { on, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
// Emit later on
process.nextTick(() => {
ee.emit('foo', 'bar');
ee.emit('foo', 42);
ee.emit('close');
});
for await (const event of on(ee, 'foo', { close: ['close'] })) {
console.log(event); // prints ['bar'] [42]
}
// the loop will exit after 'close' is emitted
console.log('done'); // prints 'done'
on(): AsyncIterator<any[]> once(): Promise<any[]> Создаёт Promise, который выполняется при возникновении указанного события у EventEmitter или отклоняется, если во время ожидания EventEmitter генерирует событие 'error'. Promise разрешается массивом всех аргументов, переданных указанному событию.
Этот метод намеренно универсален и работает с интерфейсом платформы веба EventTarget, у которого нет специальной семантики события 'error' и который не прослушивает событие 'error'.
import { once, EventEmitter } from 'node:events';
import process from 'node:process';
const ee = new EventEmitter();
process.nextTick(() => {
ee.emit('myevent', 42);
});
const [value] = await once(ee, 'myevent');
console.log(value);
const err = new Error('kaboom');
process.nextTick(() => {
ee.emit('error', err);
});
try {
await once(ee, 'myevent');
} catch (err) {
console.error('error happened', err);
}
Специальная обработка события 'error' применяется только при использовании events.once() для ожидания другого события. Если events.once() используется для ожидания самого события «error'», оно обрабатывается как любое другое событие, без специальной обработки:
import { EventEmitter, once } from 'node:events';
const ee = new EventEmitter();
once(ee, 'error')
.then(([err]) => console.log('ok', err.message))
.catch((err) => console.error('error', err.message));
ee.emit('error', new Error('boom'));
// Prints: ok boom
Для отмены ожидания события можно использовать AbortSignal:
import { EventEmitter, once } from 'node:events';
const ee = new EventEmitter();
const ac = new AbortController();
async function foo(emitter, event, signal) {
try {
await once(emitter, event, { signal });
console.log('event emitted!');
} catch (error) {
if (error.name === 'AbortError') {
console.error('Waiting for the event was canceled!');
} else {
console.error('There was an error', error.message);
}
}
}
foo(ee, 'foo', ac.signal);
ac.abort(); // Abort waiting for the event
ee.emit('foo'); // Prints: Waiting for the event was canceled!
once(): Promise<any[]> setMaxListeners(
n?: number,
...eventTargets: Array<EventTarget | EventEmitter>,
): void import { setMaxListeners, EventEmitter } from 'node:events';
const target = new EventTarget();
const emitter = new EventEmitter();
setMaxListeners(5, target, emitter);
интерфейс EventEmitter
Параметры типа
T extends EventMap<T> = DefaultEventMap Параметры типа
T extends EventMap<T> = DefaultEventMap Методы
[[EventEmitter.captureRejectionSymbol]]<K>(): void addListener<K>(): this Псевдоним для emitter.on(eventName, listener).
Добавляет функцию listener в конец массива слушателей события с именем eventName. Проверка на то, был ли уже добавлен listener, не выполняется. Несколько вызовов с одинаковым сочетанием eventName и listener приведут к многократному добавлению и вызову listener.
server.on('connection', (stream) => {
console.log('someone connected!');
});
Возвращает ссылку на EventEmitter, чтобы вызовы можно было объединять в цепочку.
По умолчанию слушатели событий вызываются в порядке их добавления. В качестве альтернативы можно использовать метод emitter.prependListener(), чтобы добавить слушатель события в начало массива слушателей.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
Добавляет функцию listener для события с именем eventName, которая срабатывает один раз. При следующем возникновении события eventName этот слушатель удаляется, а затем вызывается.
server.once('connection', (stream) => {
console.log('Ah, we have our first user!');
});
Возвращает ссылку на EventEmitter, чтобы вызовы можно было объединять в цепочку.
По умолчанию слушатели событий вызываются в порядке их добавления. В качестве альтернативы можно использовать метод emitter.prependOnceListener(), чтобы добавить слушатель события в начало массива слушателей.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
removeListener<K>(): this Удаляет указанный listener из массива слушателей события с именем eventName.
const callback = (stream) => {
console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
removeListener() удаляет из массива слушателей не более одного экземпляра слушателя. Если один и тот же слушатель был добавлен в массив слушателей указанного eventName несколько раз, для удаления каждого экземпляра необходимо вызвать removeListener() несколько раз.
При возникновении события все прикреплённые к нему слушатели вызываются в порядке добавления. Это означает, что любые вызовы removeListener() или removeAllListeners(), выполненные после возникновения события и до завершения работы последнего слушателя, не удалят их из выполняющегося emit(). Последующие события обрабатываются ожидаемым образом.
import { EventEmitter } from 'node:events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
const callbackA = () => {
console.log('A');
myEmitter.removeListener('event', callbackB);
};
const callbackB = () => {
console.log('B');
};
myEmitter.on('event', callbackA);
myEmitter.on('event', callbackB);
// callbackA removes listener callbackB but it will still be called.
// Internal listener array at time of emit [callbackA, callbackB]
myEmitter.emit('event');
// Prints:
// A
// B
// callbackB is now removed.
// Internal listener array [callbackA]
myEmitter.emit('event');
// Prints:
// A
Поскольку слушатели управляются с помощью внутреннего массива, вызов этого метода изменит индексы всех слушателей, зарегистрированных после удаляемого слушателя. Это не повлияет на порядок вызова слушателей, однако любые копии массива слушателей, возвращённые методом emitter.listeners(), потребуется создать заново.
Если одна функция была добавлена как обработчик одного события несколько раз (как в примере ниже), removeListener() удалит экземпляр, добавленный последним. В примере удаляется слушатель once('ping'):
import { EventEmitter } from 'node:events';
const ee = new EventEmitter();
function pong() {
console.log('pong');
}
ee.on('ping', pong);
ee.once('ping', pong);
ee.removeListener('ping', pong);
ee.emit('ping');
ee.emit('ping');
Возвращает ссылку на EventEmitter, чтобы вызовы можно было объединять в цепочку.
Псевдоним для emitter.removeListener().
removeAllListeners(eventName?: Key<unknown, T>): this Удаляет все слушатели или только слушателей указанного eventName.
Не рекомендуется удалять слушателей, добавленных в других частях кода, особенно если экземпляр EventEmitter был создан другим компонентом или модулем (например, сокетами или файловыми потоками).
Возвращает ссылку на EventEmitter, чтобы вызовы можно было объединять в цепочку.
setMaxListeners(n: number): this По умолчанию EventEmitters выводят предупреждение, если для определённого события добавлено более 10 слушателей. Это полезное значение по умолчанию, помогающее обнаруживать утечки памяти. Метод emitter.setMaxListeners() позволяет изменить лимит для этого конкретного экземпляра EventEmitter. Значение можно установить равным Infinity (или 0), чтобы указать неограниченное количество слушателей.
Возвращает ссылку на EventEmitter, чтобы вызовы можно было объединять в цепочку.
getMaxListeners(): number Возвращает текущее максимальное количество слушателей для EventEmitter, заданное с помощью emitter.setMaxListeners(n) или равное значению по умолчанию EventEmitter.defaultMaxListeners.
Возвращает копию массива слушателей события с именем eventName.
server.on('connection', (stream) => {
console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection')));
// Prints: [ [Function] ]
rawListeners<K>(eventName: Key<K, T>): Array<Listener2<K, T>> Возвращает копию массива слушателей события с именем eventName, включая обёртки (например, созданные методом .once()).
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
emitter.once('log', () => console.log('log once'));
// Returns a new Array with a function `onceWrapper` which has a property
// `listener` which contains the original listener bound above
const listeners = emitter.rawListeners('log');
const logFnWrapper = listeners[0];
// Logs "log once" to the console and does not unbind the `once` event
logFnWrapper.listener();
// Logs "log once" to the console and removes the listener
logFnWrapper();
emitter.on('log', () => console.log('log persistently'));
// Will return a new Array with a single function bound by `.on()` above
const newListeners = emitter.rawListeners('log');
// Logs "log persistently" twice
newListeners[0]();
emitter.emit('log');
Синхронно вызывает каждый из слушателей, зарегистрированных для события с именем eventName, в порядке их регистрации, передавая каждому из них указанные аргументы.
Возвращает true, если у события есть слушатели, и false в противном случае.
import { EventEmitter } from 'node:events';
const myEmitter = new EventEmitter();
// First listener
myEmitter.on('event', function firstListener() {
console.log('Helloooo! first listener');
});
// Second listener
myEmitter.on('event', function secondListener(arg1, arg2) {
console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
});
// Third listener
myEmitter.on('event', function thirdListener(...args) {
const parameters = args.join(', ');
console.log(`event with parameters ${parameters} in third listener`);
});
console.log(myEmitter.listeners('event'));
myEmitter.emit('event', 1, 2, 3, 4, 5);
// Prints:
// [
// [Function: firstListener],
// [Function: secondListener],
// [Function: thirdListener]
// ]
// Helloooo! first listener
// event with parameters 1, 2 in second listener
// event with parameters 1, 2, 3, 4, 5 in third listener
listenerCount<K>(): number Возвращает количество слушателей события с именем eventName. Если указан listener, метод вернёт количество его вхождений в список слушателей события.
prependListener<K>(): this Добавляет функцию listener в начало массива слушателей события с именем eventName. Проверка на то, был ли уже добавлен listener, не выполняется. Несколько вызовов с одинаковым сочетанием eventName и listener приведут к многократному добавлению и вызову listener.
server.prependListener('connection', (stream) => {
console.log('someone connected!');
});
Возвращает ссылку на EventEmitter, чтобы вызовы можно было объединять в цепочку.
prependOnceListener<K>(): this Добавляет функцию listener для события с именем eventName в начало массива слушателей; функция срабатывает один раз. При следующем возникновении события eventName этот слушатель удаляется, а затем вызывается.
server.prependOnceListener('connection', (stream) => {
console.log('Ah, we have our first user!');
});
Возвращает ссылку на EventEmitter, чтобы вызовы можно было объединять в цепочку.
eventNames(): Array<(string | symbol) & Key2<unknown, T>> Возвращает массив событий, для которых эмиттер зарегистрировал слушателей. Значения в массиве представлены строками или Symbols.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => {});
myEE.on('bar', () => {});
const sym = Symbol('symbol');
myEE.on(sym, () => {});
console.log(myEE.eventNames());
// Prints: [ 'foo', 'bar', Symbol(symbol) ]
пространство имён EventEmitter
Классы
Интегрирует EventEmitter с AsyncResource для EventEmitters, которым требуется ручное отслеживание асинхронных операций. В частности, все события, генерируемые экземплярами events.EventEmitterAsyncResource, будут выполняться в рамках его async context.
Интерфейсы
интерфейс EventEmitter.Abortable
Использование в Deno
import { EventEmitter } from "node:events";
Свойства
signal: AbortSignal | undefined Если указан, соответствующий AbortController можно использовать для отмены асинхронного действия.
интерфейс EventEmitter.EventEmitterAsyncResourceOptions
Использование в Deno
import { EventEmitter } from "node:events";
Свойства
name: string Тип асинхронного события; это свойство необходимо при непосредственном создании экземпляра EventEmitterAsyncResource, а не при создании экземпляра дочернего класса.
интерфейс EventEmitter.EventEmitterReferencingAsyncResource
Использование в Deno
import { EventEmitter } from "node:events";
Свойства
eventEmitter: EventEmitterAsyncResource интерфейс EventEmitterOptions
Использование в Deno
import { type EventEmitterOptions } from "node:events";
Свойства
captureRejections: boolean | undefined Включает автоматический перехват отклонения промиса.
интерфейс StaticEventEmitterIteratorOptions
Использование в Deno
import { type StaticEventEmitterIteratorOptions } from "node:events";
Свойства
close: string[] | undefined Имена событий, которые завершат итерацию.
highWaterMark: number | undefined Верхний порог. Эмиттер приостанавливается каждый раз, когда размер буферизованных событий превышает это значение. Поддерживается только эмиттерами, реализующими методы pause() и resume().
lowWaterMark: number | undefined Нижний порог. Эмиттер возобновляет работу каждый раз, когда размер буферизованных событий становится меньше этого значения. Поддерживается только эмиттерами, реализующими методы pause() и resume().
интерфейс StaticEventEmitterOptions
Использование в Deno
import { type StaticEventEmitterOptions } from "node:events";
Свойства
signal: AbortSignal | undefined Можно использовать для отмены ожидания событий.
псевдоним типа AnyRest
Использование в Deno
import { type AnyRest } from "node:events";
Определение
[any[]] псевдоним типа DefaultEventMap
Использование в Deno
import { type DefaultEventMap } from "node:events";
Определение
[never] псевдоним типа EventMap
Использование в Deno
import { type EventMap } from "node:events";
Параметры типа
T Определение
Record<keyof T, any[]> | DefaultEventMap псевдоним типа Key
Использование в Deno
import { type Key } from "node:events";
Параметры типа
K T Определение
T extends DefaultEventMap ? string | symbol : K | keyof T псевдоним типа Key2
Использование в Deno
import { type Key2 } from "node:events";
Параметры типа
K T Определение
T extends DefaultEventMap ? string | symbol : K & keyof T
© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/api/node/events