Files
scriptc/docs/content/limitations/builtin-function-values.mdx
T
Malte UblandClaude Opus 5.5 acfdc7fe13 Store builtin timer functions as real function values in JavaScript
`var nextTick = typeof setImmediate === "function" ? setImmediate :
setTimeout` (bcryptjs) and `cond ? setImmediate : process.nextTick`
stored the builtin as an identity token string, so typeof answered
"string" and calling it threw "nextTick is not a function". The JavaScript
identifier, `globalThis.X` and destructuring spellings of setTimeout,
setInterval, setImmediate, clearTimeout, clearInterval, clearImmediate and
queueMicrotask, and a stored process.nextTick, now read one interned
runtime function per name. Conditional, logical and assigned values carry
it like any function: typeof is "function", identity holds across
spellings, and calls validate the callback (ERR_INVALID_ARG_TYPE), coerce
the delay, pass the extra arguments and return the same numeric handles
the direct calls return, which the stored clear functions accept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:34:58 -07:00

21 lines
4.7 KiB
Plaintext

Some builtins can be stored and passed as functions:
- Lowered `node:path` functions across the bare, POSIX, and win32 modules, including optional `basename` and variadic `join`/`resolve`.
- Supported zero-argument `node:os` functions and `querystring.escape`/`unescape`.
- `util.isDeepStrictEqual`, `styleText`, `stripVTControlCharacters`, `toUSVString`, `inherits`, `deprecate`, `callbackify`, `debuglog`, and `debug`.
- `fs.existsSync`, `unlinkSync`, `chmodSync`, `chownSync`, `renameSync`, and `closeSync`, and `fs/promises.unlink`, `chmod`, and `rename`.
In JavaScript, `setTimeout`, `setInterval`, `setImmediate`, `clearTimeout`, `clearInterval`, `clearImmediate`, `queueMicrotask`, and `process.nextTick` are function values wherever they are stored, including conditional and logical expressions and assignments: `typeof` answers `"function"`, identity holds across spellings, and calls schedule as the direct calls do, returning the same numeric timer handles. Calls through these values bypass `node:test` mock timers. Other builtin globals stored in JavaScript remain opaque identity values.
Other immutable aliases of table-backed Node builtins support direct calls, but cannot be passed elsewhere. `util.promisify` supports compile-time conversions of `child_process.execFile`, `child_process.exec`, `setTimeout` and `setImmediate` (to the `timers/promises` functions, as in Node), `stream.finished` and `stream.pipeline` (to the `stream/promises` functions, as in Node), the `zlib` callback one-shots `deflate`, `inflate`, `deflateRaw`, `inflateRaw`, `gzip`, `gunzip` and `unzip` (with or without options), the `crypto` callback functions `randomBytes`, `pbkdf2`, `scrypt`, `hkdf`, `randomFill`, `randomInt` and `generateKey`, `dns.lookup` (settling with `{ address, family }`, or the address array with `all: true`) and `dns.lookupService` (settling with `{ hostname, service }`), and the `fs` callback functions that have an `fs/promises` counterpart (`access`, `appendFile`, `chmod`, `chown`, `copyFile`, `lchown`, `link`, `lstat`, `lutimes`, `mkdir`, `mkdtemp`, `readFile`, `readdir`, `readlink`, `realpath`, `rename`, `rm`, `rmdir`, `stat`, `statfs`, `symlink`, `truncate`, `unlink`, `utimes`, and `writeFile`); calls through the converted function lower as the `fs/promises` call.
`util.styleText` supports standard formats and aliases, `#RGB` and `#RRGGBB` hex colors, arrays of formats, nested ANSI resets, and explicit color enabling with `{ validateStream: false }`. Native calls accept standard process streams; custom native streams and mutations to `util.inspect.colors` remain unsupported.
`util.inherits` links the prototypes of constructor functions, and `util.deprecate`, `util.callbackify`, and `util.debuglog` return native function values that forward receivers and arguments. Class constructors passed to `util.inherits` or `util.deprecate` are refused. Deprecation warnings are emitted on the next tick and follow assignments to `process.noDeprecation` and `process.throwDeprecation`; compiled binaries take no Node command-line flags such as `--no-deprecation` or `--trace-deprecation`, and `process.traceDeprecation` is unsupported. A stored `util.deprecate` reports a `length` of 4, where Node reports 3. In TypeScript, a `util.callbackify` result must reach a callback whose error parameter accepts `null`; the @types/node overloads that type it as non-null are refused. `util.debuglog` reads `NODE_DEBUG` as the process started. Its `%s` refuses functions and objects with symbol-keyed members, `%o` refuses objects, and object arguments are refused on a color terminal.
`util.isDeepStrictEqual` supports primitives, ordinary records and arrays, cycles, enumerable string and symbol properties, and byte views. Its optional third argument skips prototype and constructor comparisons. Structural comparisons of native Maps, Sets, class instances, Errors, proxies, accessor properties, and function-valued own `constructor` properties remain refused.
Synchronous and promise filesystem APIs with trailing arguments that affect behavior remain call-only. This includes writers, open, directory creation/removal, metadata readers, and directory readers. Passing them as values could discard modes, flags, encodings, or options during function-signature adaptation.
Native error-first filesystem callbacks can be stored and passed to platform adapters. Reads support Buffer and UTF-8 results; writes preserve string flags and modes; copy follows `fs.cp`. Reads and writes reject already-aborted signals, but native file operations complete synchronously before the deferred callback, so cancellation cannot interrupt I/O in progress. Recursive directory reads and Dirent results report a native limitation. `fs.glob` compiles only as a direct call; a stored `fs.glob` value throws `SC2020`.