@scriptc/compiler 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1218) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +682 -50
  2. package/ambient/scriptc.d.ts +134 -0
  3. package/dist/backend/cycle-analysis.d.ts +1 -1
  4. package/dist/backend/cycle-analysis.js +1 -0
  5. package/dist/backend/cycle-analysis.js.map +1 -1
  6. package/dist/backend/cycle-analysis.test.js +13 -1
  7. package/dist/backend/cycle-analysis.test.js.map +1 -1
  8. package/dist/backend/cycle-mutability.js +16 -5
  9. package/dist/backend/cycle-mutability.js.map +1 -1
  10. package/dist/backend/executable-features.js +13 -0
  11. package/dist/backend/executable-features.js.map +1 -1
  12. package/dist/backend/immutability.test.js +1 -1
  13. package/dist/backend/library-pack.js +6 -0
  14. package/dist/backend/library-pack.js.map +1 -1
  15. package/dist/backend/llvm/alloc.d.ts +41 -4
  16. package/dist/backend/llvm/alloc.js +138 -7
  17. package/dist/backend/llvm/alloc.js.map +1 -1
  18. package/dist/backend/llvm/alloc.test.js +30 -1
  19. package/dist/backend/llvm/alloc.test.js.map +1 -1
  20. package/dist/backend/llvm/appended-array-literals.test.js +1 -1
  21. package/dist/backend/llvm/array-search.test.js +1 -1
  22. package/dist/backend/llvm/blocks.d.ts +8 -0
  23. package/dist/backend/llvm/blocks.js +43 -1
  24. package/dist/backend/llvm/blocks.js.map +1 -1
  25. package/dist/backend/llvm/blocks.test.js +22 -1
  26. package/dist/backend/llvm/blocks.test.js.map +1 -1
  27. package/dist/backend/llvm/byte-numbers.js +15 -5
  28. package/dist/backend/llvm/byte-numbers.js.map +1 -1
  29. package/dist/backend/llvm/bytes-alias.d.ts +14 -0
  30. package/dist/backend/llvm/bytes-alias.js +20 -0
  31. package/dist/backend/llvm/bytes-alias.js.map +1 -0
  32. package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
  33. package/dist/backend/llvm/bytes-loop-versions.js +506 -0
  34. package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
  35. package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
  36. package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
  37. package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
  38. package/dist/backend/llvm/call-lifetimes.js +50 -1
  39. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  40. package/dist/backend/llvm/call-lifetimes.test.js +34 -0
  41. package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
  42. package/dist/backend/llvm/checked-narrows.test.js +1 -1
  43. package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
  44. package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
  45. package/dist/backend/llvm/classes.d.ts +11 -0
  46. package/dist/backend/llvm/classes.js +71 -14
  47. package/dist/backend/llvm/classes.js.map +1 -1
  48. package/dist/backend/llvm/classes.test.js +58 -8
  49. package/dist/backend/llvm/classes.test.js.map +1 -1
  50. package/dist/backend/llvm/common.js +1 -0
  51. package/dist/backend/llvm/common.js.map +1 -1
  52. package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
  53. package/dist/backend/llvm/constant-callbacks.js +55 -12
  54. package/dist/backend/llvm/constant-callbacks.js.map +1 -1
  55. package/dist/backend/llvm/constant-callbacks.test.js +88 -1
  56. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
  57. package/dist/backend/llvm/counted-loops.d.ts +4 -0
  58. package/dist/backend/llvm/counted-loops.js +37 -0
  59. package/dist/backend/llvm/counted-loops.js.map +1 -1
  60. package/dist/backend/llvm/dense-array-access.d.ts +12 -3
  61. package/dist/backend/llvm/dense-array-access.js +72 -14
  62. package/dist/backend/llvm/dense-array-access.js.map +1 -1
  63. package/dist/backend/llvm/dense-array-access.test.js +59 -3
  64. package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
  65. package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
  66. package/dist/backend/llvm/dense-array-loops.js +162 -0
  67. package/dist/backend/llvm/dense-array-loops.js.map +1 -0
  68. package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
  69. package/dist/backend/llvm/dense-array-loops.test.js +128 -0
  70. package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
  71. package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
  72. package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
  73. package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
  74. package/dist/backend/llvm/dyn.d.ts +28 -4
  75. package/dist/backend/llvm/dyn.js +293 -178
  76. package/dist/backend/llvm/dyn.js.map +1 -1
  77. package/dist/backend/llvm/emit-function.d.ts +64 -0
  78. package/dist/backend/llvm/emit-function.js +1190 -0
  79. package/dist/backend/llvm/emit-function.js.map +1 -0
  80. package/dist/backend/llvm/emit-module.d.ts +24 -0
  81. package/dist/backend/llvm/emit-module.js +1535 -0
  82. package/dist/backend/llvm/emit-module.js.map +1 -0
  83. package/dist/backend/llvm/emit-statements.d.ts +58 -0
  84. package/dist/backend/llvm/emit-statements.js +1964 -0
  85. package/dist/backend/llvm/emit-statements.js.map +1 -0
  86. package/dist/backend/llvm/emitter.d.ts +547 -283
  87. package/dist/backend/llvm/emitter.js +689 -4643
  88. package/dist/backend/llvm/emitter.js.map +1 -1
  89. package/dist/backend/llvm/emitter.test.js +57 -3
  90. package/dist/backend/llvm/emitter.test.js.map +1 -1
  91. package/dist/backend/llvm/expr-async.js +73 -46
  92. package/dist/backend/llvm/expr-async.js.map +1 -1
  93. package/dist/backend/llvm/expr-async.test.js +1 -1
  94. package/dist/backend/llvm/expr-bytes.d.ts +2 -0
  95. package/dist/backend/llvm/expr-bytes.js +76 -29
  96. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  97. package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
  98. package/dist/backend/llvm/expr-callbacks.js +48 -11
  99. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  100. package/dist/backend/llvm/expr-calls.d.ts +1 -1
  101. package/dist/backend/llvm/expr-calls.js +71 -53
  102. package/dist/backend/llvm/expr-calls.js.map +1 -1
  103. package/dist/backend/llvm/expr-calls.test.js +1 -1
  104. package/dist/backend/llvm/expr-containers.js +39 -15
  105. package/dist/backend/llvm/expr-containers.js.map +1 -1
  106. package/dist/backend/llvm/expr-control.js +16 -16
  107. package/dist/backend/llvm/expr-control.js.map +1 -1
  108. package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
  109. package/dist/backend/llvm/expr-dynamic.js +67 -62
  110. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  111. package/dist/backend/llvm/expr-primitives.js +121 -25
  112. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  113. package/dist/backend/llvm/expr-primitives.test.js +2 -2
  114. package/dist/backend/llvm/expr-records.d.ts +1 -1
  115. package/dist/backend/llvm/expr-records.js +32 -11
  116. package/dist/backend/llvm/expr-records.js.map +1 -1
  117. package/dist/backend/llvm/expr-stream-bridges.js +54 -12
  118. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  119. package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
  120. package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
  121. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  122. package/dist/backend/llvm/int32-abi.test.js +2 -2
  123. package/dist/backend/llvm/integer-clones.test.js +3 -3
  124. package/dist/backend/llvm/integer-remainder.d.ts +34 -13
  125. package/dist/backend/llvm/integer-remainder.js +156 -22
  126. package/dist/backend/llvm/integer-remainder.js.map +1 -1
  127. package/dist/backend/llvm/intern-tables.test.js +1 -1
  128. package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
  129. package/dist/backend/llvm/jsval-encoding.js +20 -0
  130. package/dist/backend/llvm/jsval-encoding.js.map +1 -0
  131. package/dist/backend/llvm/jsval.d.ts +12 -0
  132. package/dist/backend/llvm/jsval.js +488 -0
  133. package/dist/backend/llvm/jsval.js.map +1 -0
  134. package/dist/backend/llvm/lazy-captures.d.ts +12 -2
  135. package/dist/backend/llvm/lazy-captures.js +39 -17
  136. package/dist/backend/llvm/lazy-captures.js.map +1 -1
  137. package/dist/backend/llvm/lib-abi.js +1 -1
  138. package/dist/backend/llvm/lib-abi.js.map +1 -1
  139. package/dist/backend/llvm/lib-connect.js +1 -1
  140. package/dist/backend/llvm/lib-connect.js.map +1 -1
  141. package/dist/backend/llvm/lib-datagram.js +14 -8
  142. package/dist/backend/llvm/lib-datagram.js.map +1 -1
  143. package/dist/backend/llvm/lib-dispatch.js +189 -23
  144. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  145. package/dist/backend/llvm/lib-filesystem.js +42 -13
  146. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  147. package/dist/backend/llvm/lib-http2.js +3 -3
  148. package/dist/backend/llvm/lib-http2.js.map +1 -1
  149. package/dist/backend/llvm/lib-lookup.js +2 -2
  150. package/dist/backend/llvm/lib-lookup.js.map +1 -1
  151. package/dist/backend/llvm/lib-network.js +56 -22
  152. package/dist/backend/llvm/lib-network.js.map +1 -1
  153. package/dist/backend/llvm/lib-process.js +90 -50
  154. package/dist/backend/llvm/lib-process.js.map +1 -1
  155. package/dist/backend/llvm/lib-shared.d.ts +12 -0
  156. package/dist/backend/llvm/lib-shared.js +187 -6
  157. package/dist/backend/llvm/lib-shared.js.map +1 -1
  158. package/dist/backend/llvm/lib-stream.js +46 -16
  159. package/dist/backend/llvm/lib-stream.js.map +1 -1
  160. package/dist/backend/llvm/lib-test.js +43 -7
  161. package/dist/backend/llvm/lib-test.js.map +1 -1
  162. package/dist/backend/llvm/lib-tls.js +4 -9
  163. package/dist/backend/llvm/lib-tls.js.map +1 -1
  164. package/dist/backend/llvm/local-array-reads.js +2 -2
  165. package/dist/backend/llvm/local-array-reads.test.js +1 -1
  166. package/dist/backend/llvm/local-extents.d.ts +19 -0
  167. package/dist/backend/llvm/local-extents.js +169 -0
  168. package/dist/backend/llvm/local-extents.js.map +1 -0
  169. package/dist/backend/llvm/local-extents.test.d.ts +1 -0
  170. package/dist/backend/llvm/local-extents.test.js +92 -0
  171. package/dist/backend/llvm/local-extents.test.js.map +1 -0
  172. package/dist/backend/llvm/local-union-storage.js +7 -7
  173. package/dist/backend/llvm/local-union-storage.js.map +1 -1
  174. package/dist/backend/llvm/local-union-storage.test.js +2 -2
  175. package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
  176. package/dist/backend/llvm/map-number-lookup.js +2 -2
  177. package/dist/backend/llvm/map-number-lookup.test.js +2 -2
  178. package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
  179. package/dist/backend/llvm/narrow-guards.d.ts +38 -0
  180. package/dist/backend/llvm/narrow-guards.js +151 -0
  181. package/dist/backend/llvm/narrow-guards.js.map +1 -0
  182. package/dist/backend/llvm/nullable-unions.d.ts +64 -6
  183. package/dist/backend/llvm/nullable-unions.js +103 -6
  184. package/dist/backend/llvm/nullable-unions.js.map +1 -1
  185. package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
  186. package/dist/backend/llvm/nullable-unions.test.js +65 -0
  187. package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
  188. package/dist/backend/llvm/publish.d.ts +4 -0
  189. package/dist/backend/llvm/publish.js +14 -2
  190. package/dist/backend/llvm/publish.js.map +1 -1
  191. package/dist/backend/llvm/publish.test.js +1 -1
  192. package/dist/backend/llvm/receivers.d.ts +31 -0
  193. package/dist/backend/llvm/receivers.js +395 -0
  194. package/dist/backend/llvm/receivers.js.map +1 -0
  195. package/dist/backend/llvm/record-results.d.ts +12 -1
  196. package/dist/backend/llvm/record-results.js +64 -4
  197. package/dist/backend/llvm/record-results.js.map +1 -1
  198. package/dist/backend/llvm/reference-effects.js +9 -0
  199. package/dist/backend/llvm/reference-effects.js.map +1 -1
  200. package/dist/backend/llvm/reference-writes.d.ts +4 -0
  201. package/dist/backend/llvm/reference-writes.js +142 -6
  202. package/dist/backend/llvm/reference-writes.js.map +1 -1
  203. package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
  204. package/dist/backend/llvm/reference-writes.test.js +88 -0
  205. package/dist/backend/llvm/reference-writes.test.js.map +1 -0
  206. package/dist/backend/llvm/regex-matchers.d.ts +8 -0
  207. package/dist/backend/llvm/regex-matchers.js +33 -0
  208. package/dist/backend/llvm/regex-matchers.js.map +1 -1
  209. package/dist/backend/llvm/regex-matchers.test.js +23 -1
  210. package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
  211. package/dist/backend/llvm/regions.d.ts +1 -1
  212. package/dist/backend/llvm/regions.js +9 -6
  213. package/dist/backend/llvm/regions.js.map +1 -1
  214. package/dist/backend/llvm/regions.test.js +1 -1
  215. package/dist/backend/llvm/shapes.d.ts +66 -43
  216. package/dist/backend/llvm/shapes.js +280 -21
  217. package/dist/backend/llvm/shapes.js.map +1 -1
  218. package/dist/backend/llvm/shapes.test.js +37 -3
  219. package/dist/backend/llvm/shapes.test.js.map +1 -1
  220. package/dist/backend/llvm/split-loops.js +2 -2
  221. package/dist/backend/llvm/split-loops.js.map +1 -1
  222. package/dist/backend/llvm/stack-objects.d.ts +26 -6
  223. package/dist/backend/llvm/stack-objects.js +133 -10
  224. package/dist/backend/llvm/stack-objects.js.map +1 -1
  225. package/dist/backend/llvm/stack-objects.test.js +55 -1
  226. package/dist/backend/llvm/stack-objects.test.js.map +1 -1
  227. package/dist/backend/llvm/stack-unions.test.js +1 -1
  228. package/dist/backend/llvm/string-construction.test.js +1 -1
  229. package/dist/backend/llvm/string-lifetimes.test.js +15 -14
  230. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  231. package/dist/backend/llvm/string-slices.d.ts +25 -0
  232. package/dist/backend/llvm/string-slices.js +207 -1
  233. package/dist/backend/llvm/string-slices.js.map +1 -1
  234. package/dist/backend/llvm/string-slices.test.js +139 -2
  235. package/dist/backend/llvm/string-slices.test.js.map +1 -1
  236. package/dist/backend/llvm/switch-dispatch.test.js +2 -2
  237. package/dist/backend/llvm/thread-slots.d.ts +5 -0
  238. package/dist/backend/llvm/thread-slots.js +142 -0
  239. package/dist/backend/llvm/thread-slots.js.map +1 -0
  240. package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
  241. package/dist/backend/llvm/thread-slots.test.js +110 -0
  242. package/dist/backend/llvm/thread-slots.test.js.map +1 -0
  243. package/dist/backend/llvm/union-repr.d.ts +7 -7
  244. package/dist/backend/llvm/union-repr.js +18 -2
  245. package/dist/backend/llvm/union-repr.js.map +1 -1
  246. package/dist/backend/llvm/union-retype.test.js +17 -3
  247. package/dist/backend/llvm/union-retype.test.js.map +1 -1
  248. package/dist/backend/llvm/walkers.d.ts +2 -2
  249. package/dist/backend/llvm/walkers.js +51 -26
  250. package/dist/backend/llvm/walkers.js.map +1 -1
  251. package/dist/backend/llvm/wasm-modules.d.ts +16 -0
  252. package/dist/backend/llvm/wasm-modules.js +66 -0
  253. package/dist/backend/llvm/wasm-modules.js.map +1 -0
  254. package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
  255. package/dist/backend/llvm/wrapping-sums.js +11 -3
  256. package/dist/backend/llvm/wrapping-sums.js.map +1 -1
  257. package/dist/backend/mangle.d.ts +7 -0
  258. package/dist/backend/mangle.js +11 -0
  259. package/dist/backend/mangle.js.map +1 -1
  260. package/dist/backend/may-throw.d.ts +3 -0
  261. package/dist/backend/may-throw.js +4 -2
  262. package/dist/backend/may-throw.js.map +1 -1
  263. package/dist/backend/may-throw.test.js +1 -1
  264. package/dist/backend/native/contracts.d.ts +37 -0
  265. package/dist/backend/native/executable.js +192 -137
  266. package/dist/backend/native/executable.js.map +1 -1
  267. package/dist/backend/native/library.js +1 -0
  268. package/dist/backend/native/library.js.map +1 -1
  269. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  270. package/dist/backend/native/runtime-inputs.js +1 -0
  271. package/dist/backend/native/runtime-inputs.js.map +1 -1
  272. package/dist/backend/native-link-info-core.d.ts +30 -0
  273. package/dist/backend/native-link-info-core.js.map +1 -1
  274. package/dist/backend/publication.test.js +1 -1
  275. package/dist/backend/runtime-pack-core.d.ts +9 -1
  276. package/dist/backend/runtime-pack-core.js +10 -1
  277. package/dist/backend/runtime-pack-core.js.map +1 -1
  278. package/dist/backend/runtime-pack-native.js +1 -1
  279. package/dist/backend/runtime-pack-native.js.map +1 -1
  280. package/dist/backend/runtime-pack-native.test.d.ts +1 -0
  281. package/dist/backend/runtime-pack-native.test.js +31 -0
  282. package/dist/backend/runtime-pack-native.test.js.map +1 -0
  283. package/dist/backend/runtime-pack-targets.test.js +5 -0
  284. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  285. package/dist/backend/runtime-pack.test.js +5 -0
  286. package/dist/backend/runtime-pack.test.js.map +1 -1
  287. package/dist/backend/stack-observations.d.ts +22 -0
  288. package/dist/backend/stack-observations.js +382 -0
  289. package/dist/backend/stack-observations.js.map +1 -0
  290. package/dist/backend/stack-observations.test.d.ts +1 -0
  291. package/dist/backend/stack-observations.test.js +233 -0
  292. package/dist/backend/stack-observations.test.js.map +1 -0
  293. package/dist/backend/target-diagnostics.js +8 -0
  294. package/dist/backend/target-diagnostics.js.map +1 -1
  295. package/dist/backend/target-diagnostics.test.js +1 -1
  296. package/dist/backend/warm-cache.js +5 -0
  297. package/dist/backend/warm-cache.js.map +1 -1
  298. package/dist/backend/young-nursery.d.ts +7 -0
  299. package/dist/backend/young-nursery.js +10 -0
  300. package/dist/backend/young-nursery.js.map +1 -0
  301. package/dist/cli/command.js +44 -4
  302. package/dist/cli/command.js.map +1 -1
  303. package/dist/cli/usage.d.ts +11 -1
  304. package/dist/cli/usage.js +20 -1
  305. package/dist/cli/usage.js.map +1 -1
  306. package/dist/compat/fetch-profile.js +10 -1
  307. package/dist/compat/fetch-profile.js.map +1 -1
  308. package/dist/compile-types.d.ts +13 -0
  309. package/dist/contracts/check.js +24 -6
  310. package/dist/contracts/check.js.map +1 -1
  311. package/dist/contracts/int32-elements.d.ts +115 -0
  312. package/dist/contracts/int32-elements.js +1179 -0
  313. package/dist/contracts/int32-elements.js.map +1 -0
  314. package/dist/coverage/report.d.ts +16 -0
  315. package/dist/coverage/report.js +182 -1
  316. package/dist/coverage/report.js.map +1 -1
  317. package/dist/coverage/surface-manifest.js +16 -3
  318. package/dist/coverage/surface-manifest.js.map +1 -1
  319. package/dist/coverage/verdict-cache.d.ts +2 -0
  320. package/dist/coverage/verdict-cache.js +12 -0
  321. package/dist/coverage/verdict-cache.js.map +1 -1
  322. package/dist/coverage/verdict-cache.test.js +2 -1
  323. package/dist/coverage/verdict-cache.test.js.map +1 -1
  324. package/dist/diagnostics/diagnostic.d.ts +10 -6
  325. package/dist/diagnostics/diagnostic.js +29 -21
  326. package/dist/diagnostics/diagnostic.js.map +1 -1
  327. package/dist/diagnostics/envelope.d.ts +39 -2
  328. package/dist/diagnostics/envelope.js.map +1 -1
  329. package/dist/diagnostics/render.d.ts +7 -0
  330. package/dist/diagnostics/render.js +50 -13
  331. package/dist/diagnostics/render.js.map +1 -1
  332. package/dist/diagnostics/render.test.d.ts +1 -0
  333. package/dist/diagnostics/render.test.js +49 -0
  334. package/dist/diagnostics/render.test.js.map +1 -0
  335. package/dist/executable/executable-cache.d.ts +17 -0
  336. package/dist/executable/executable-cache.js +13 -1
  337. package/dist/executable/executable-cache.js.map +1 -1
  338. package/dist/executable/executable-cache.test.js +7 -1
  339. package/dist/executable/executable-cache.test.js.map +1 -1
  340. package/dist/executable/prepare.js +2 -1
  341. package/dist/executable/prepare.js.map +1 -1
  342. package/dist/frontend/analysis.js +6 -1
  343. package/dist/frontend/analysis.js.map +1 -1
  344. package/dist/frontend/builtin-modules.d.ts +16 -2
  345. package/dist/frontend/builtin-modules.js +40 -7
  346. package/dist/frontend/builtin-modules.js.map +1 -1
  347. package/dist/frontend/cjs-syntax.js +52 -51
  348. package/dist/frontend/cjs-syntax.js.map +1 -1
  349. package/dist/frontend/contract-types.d.ts +3 -0
  350. package/dist/frontend/contract-types.js +36 -7
  351. package/dist/frontend/contract-types.js.map +1 -1
  352. package/dist/frontend/experimental-import.d.ts +5 -1
  353. package/dist/frontend/experimental-import.js +26 -7
  354. package/dist/frontend/experimental-import.js.map +1 -1
  355. package/dist/frontend/fork-target.js +20 -22
  356. package/dist/frontend/fork-target.js.map +1 -1
  357. package/dist/frontend/fork-target.test.js +2 -1
  358. package/dist/frontend/fork-target.test.js.map +1 -1
  359. package/dist/frontend/function-completion.js +6 -6
  360. package/dist/frontend/function-completion.js.map +1 -1
  361. package/dist/frontend/helper-tokens.js +15 -3
  362. package/dist/frontend/helper-tokens.js.map +1 -1
  363. package/dist/frontend/helper-tokens.test.js +7 -1
  364. package/dist/frontend/helper-tokens.test.js.map +1 -1
  365. package/dist/frontend/inferred-js-diagnostics.js +14 -17
  366. package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
  367. package/dist/frontend/input-tracker.d.ts +3 -0
  368. package/dist/frontend/input-tracker.js +32 -3
  369. package/dist/frontend/input-tracker.js.map +1 -1
  370. package/dist/frontend/lib-contract.js +36 -32
  371. package/dist/frontend/lib-contract.js.map +1 -1
  372. package/dist/frontend/lib-exports.js +3 -3
  373. package/dist/frontend/lib-exports.js.map +1 -1
  374. package/dist/frontend/lowering/array-values.d.ts +8 -3
  375. package/dist/frontend/lowering/array-values.js +60 -11
  376. package/dist/frontend/lowering/array-values.js.map +1 -1
  377. package/dist/frontend/lowering/assert-instances.js +4 -4
  378. package/dist/frontend/lowering/assert-instances.js.map +1 -1
  379. package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
  380. package/dist/frontend/lowering/assertion-identity.js +70 -0
  381. package/dist/frontend/lowering/assertion-identity.js.map +1 -0
  382. package/dist/frontend/lowering/assertion-members.d.ts +28 -0
  383. package/dist/frontend/lowering/assertion-members.js +185 -0
  384. package/dist/frontend/lowering/assertion-members.js.map +1 -0
  385. package/dist/frontend/lowering/binding-analysis.js +27 -20
  386. package/dist/frontend/lowering/binding-analysis.js.map +1 -1
  387. package/dist/frontend/lowering/builtin-calls.js +63 -5
  388. package/dist/frontend/lowering/builtin-calls.js.map +1 -1
  389. package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
  390. package/dist/frontend/lowering/builtin-function-fences.js +42 -0
  391. package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
  392. package/dist/frontend/lowering/builtins/arguments.js +1 -1
  393. package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
  394. package/dist/frontend/lowering/builtins/async-context.js +53 -52
  395. package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
  396. package/dist/frontend/lowering/builtins/atomics.js +6 -6
  397. package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
  398. package/dist/frontend/lowering/builtins/blob.js +8 -6
  399. package/dist/frontend/lowering/builtins/blob.js.map +1 -1
  400. package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
  401. package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
  402. package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
  403. package/dist/frontend/lowering/builtins/callable-aliases.js +16 -5
  404. package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
  405. package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
  406. package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
  407. package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
  408. package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
  409. package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
  410. package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
  411. package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
  412. package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
  413. package/dist/frontend/lowering/builtins/child-process.js +85 -61
  414. package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
  415. package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
  416. package/dist/frontend/lowering/builtins/class-values.js +226 -0
  417. package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
  418. package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
  419. package/dist/frontend/lowering/builtins/compression.js +107 -44
  420. package/dist/frontend/lowering/builtins/compression.js.map +1 -1
  421. package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
  422. package/dist/frontend/lowering/builtins/constants.js +28 -7
  423. package/dist/frontend/lowering/builtins/constants.js.map +1 -1
  424. package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
  425. package/dist/frontend/lowering/builtins/crypto.js +211 -37
  426. package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
  427. package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
  428. package/dist/frontend/lowering/builtins/dates.js +92 -16
  429. package/dist/frontend/lowering/builtins/dates.js.map +1 -1
  430. package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
  431. package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
  432. package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
  433. package/dist/frontend/lowering/builtins/environment.js +3 -3
  434. package/dist/frontend/lowering/builtins/environment.js.map +1 -1
  435. package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
  436. package/dist/frontend/lowering/builtins/errors.js +169 -3
  437. package/dist/frontend/lowering/builtins/errors.js.map +1 -1
  438. package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
  439. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  440. package/dist/frontend/lowering/builtins/filesystem.js +77 -77
  441. package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
  442. package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
  443. package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
  444. package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
  445. package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
  446. package/dist/frontend/lowering/builtins/ipc.js +45 -8
  447. package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
  448. package/dist/frontend/lowering/builtins/json.js +232 -24
  449. package/dist/frontend/lowering/builtins/json.js.map +1 -1
  450. package/dist/frontend/lowering/builtins/key-object.js +4 -4
  451. package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
  452. package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
  453. package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
  454. package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
  455. package/dist/frontend/lowering/builtins/module-calls.js +55 -44
  456. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  457. package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
  458. package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
  459. package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
  460. package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
  461. package/dist/frontend/lowering/builtins/navigator.js +40 -0
  462. package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
  463. package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
  464. package/dist/frontend/lowering/builtins/net-address.js +156 -0
  465. package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
  466. package/dist/frontend/lowering/builtins/numbers.js +25 -9
  467. package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
  468. package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
  469. package/dist/frontend/lowering/builtins/operating-system.js +25 -12
  470. package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
  471. package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
  472. package/dist/frontend/lowering/builtins/performance.js +259 -8
  473. package/dist/frontend/lowering/builtins/performance.js.map +1 -1
  474. package/dist/frontend/lowering/builtins/process.d.ts +32 -1
  475. package/dist/frontend/lowering/builtins/process.js +461 -99
  476. package/dist/frontend/lowering/builtins/process.js.map +1 -1
  477. package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
  478. package/dist/frontend/lowering/builtins/promises.js +326 -43
  479. package/dist/frontend/lowering/builtins/promises.js.map +1 -1
  480. package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
  481. package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
  482. package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
  483. package/dist/frontend/lowering/builtins/properties.js +37 -1
  484. package/dist/frontend/lowering/builtins/properties.js.map +1 -1
  485. package/dist/frontend/lowering/builtins/querystring.js +14 -14
  486. package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
  487. package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
  488. package/dist/frontend/lowering/builtins/readline.js +136 -39
  489. package/dist/frontend/lowering/builtins/readline.js.map +1 -1
  490. package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
  491. package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
  492. package/dist/frontend/lowering/builtins/reflection.js +16 -14
  493. package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
  494. package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
  495. package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
  496. package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
  497. package/dist/frontend/lowering/builtins/strings.js +101 -12
  498. package/dist/frontend/lowering/builtins/strings.js.map +1 -1
  499. package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
  500. package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
  501. package/dist/frontend/lowering/builtins/timers.js +75 -30
  502. package/dist/frontend/lowering/builtins/timers.js.map +1 -1
  503. package/dist/frontend/lowering/builtins/url.d.ts +3 -0
  504. package/dist/frontend/lowering/builtins/url.js +120 -17
  505. package/dist/frontend/lowering/builtins/url.js.map +1 -1
  506. package/dist/frontend/lowering/builtins/util-types.js +20 -4
  507. package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
  508. package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
  509. package/dist/frontend/lowering/builtins/v8.js +105 -0
  510. package/dist/frontend/lowering/builtins/v8.js.map +1 -0
  511. package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
  512. package/dist/frontend/lowering/builtins/webassembly.js +388 -0
  513. package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
  514. package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
  515. package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
  516. package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
  517. package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
  518. package/dist/frontend/lowering/builtins/workers.js +193 -8
  519. package/dist/frontend/lowering/builtins/workers.js.map +1 -1
  520. package/dist/frontend/lowering/call-arguments.js +69 -14
  521. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  522. package/dist/frontend/lowering/call-signatures.d.ts +19 -1
  523. package/dist/frontend/lowering/call-signatures.js +254 -47
  524. package/dist/frontend/lowering/call-signatures.js.map +1 -1
  525. package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
  526. package/dist/frontend/lowering/checked-promise-all.js +1 -1
  527. package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
  528. package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
  529. package/dist/frontend/lowering/cjs-exports-object.js +528 -0
  530. package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
  531. package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
  532. package/dist/frontend/lowering/cjs-inline-require.js +314 -0
  533. package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
  534. package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
  535. package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
  536. package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
  537. package/dist/frontend/lowering/class-attributes.d.ts +19 -0
  538. package/dist/frontend/lowering/class-attributes.js +378 -0
  539. package/dist/frontend/lowering/class-attributes.js.map +1 -0
  540. package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
  541. package/dist/frontend/lowering/class-callbacks.js +21 -10
  542. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  543. package/dist/frontend/lowering/class-construction.js +49 -4
  544. package/dist/frontend/lowering/class-construction.js.map +1 -1
  545. package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
  546. package/dist/frontend/lowering/class-descriptors.js +8 -8
  547. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  548. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
  549. package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
  550. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  551. package/dist/frontend/lowering/class-instance-constructor.js +1 -1
  552. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  553. package/dist/frontend/lowering/class-iterables.d.ts +11 -0
  554. package/dist/frontend/lowering/class-iterables.js +31 -0
  555. package/dist/frontend/lowering/class-iterables.js.map +1 -0
  556. package/dist/frontend/lowering/class-method-mutations.js +73 -35
  557. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  558. package/dist/frontend/lowering/class-method-values.js +56 -10
  559. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  560. package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
  561. package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
  562. package/dist/frontend/lowering/class-protocols.js +25 -44
  563. package/dist/frontend/lowering/class-protocols.js.map +1 -1
  564. package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
  565. package/dist/frontend/lowering/class-prototypes.js +80 -18
  566. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  567. package/dist/frontend/lowering/class-runtime-statics.js +1 -1
  568. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  569. package/dist/frontend/lowering/class-static-data.js +2 -2
  570. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  571. package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
  572. package/dist/frontend/lowering/class-to-primitive.js +261 -0
  573. package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
  574. package/dist/frontend/lowering/class-unions.d.ts +25 -0
  575. package/dist/frontend/lowering/class-unions.js +102 -1
  576. package/dist/frontend/lowering/class-unions.js.map +1 -1
  577. package/dist/frontend/lowering/code-generation.d.ts +14 -0
  578. package/dist/frontend/lowering/code-generation.js +127 -0
  579. package/dist/frontend/lowering/code-generation.js.map +1 -0
  580. package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
  581. package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
  582. package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
  583. package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
  584. package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
  585. package/dist/frontend/lowering/coercions/structural.js +35 -3
  586. package/dist/frontend/lowering/coercions/structural.js.map +1 -1
  587. package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
  588. package/dist/frontend/lowering/coercions/unions.js +57 -1
  589. package/dist/frontend/lowering/coercions/unions.js.map +1 -1
  590. package/dist/frontend/lowering/collection-ingestion.js +2 -2
  591. package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
  592. package/dist/frontend/lowering/collection-narrowing.js +2 -4
  593. package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
  594. package/dist/frontend/lowering/construction-escapes.js +8 -8
  595. package/dist/frontend/lowering/construction-escapes.js.map +1 -1
  596. package/dist/frontend/lowering/construction-escapes.test.js +4 -4
  597. package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
  598. package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
  599. package/dist/frontend/lowering/constructor-returns.js +477 -0
  600. package/dist/frontend/lowering/constructor-returns.js.map +1 -0
  601. package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
  602. package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
  603. package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
  604. package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
  605. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  606. package/dist/frontend/lowering/containers/array-concat.js +1 -1
  607. package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
  608. package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
  609. package/dist/frontend/lowering/containers/array-construction.js +51 -13
  610. package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
  611. package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
  612. package/dist/frontend/lowering/containers/array-from-async.js +159 -14
  613. package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
  614. package/dist/frontend/lowering/containers/array-methods.js +89 -77
  615. package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
  616. package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
  617. package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
  618. package/dist/frontend/lowering/containers/bytes.js +161 -101
  619. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  620. package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
  621. package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
  622. package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
  623. package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
  624. package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
  625. package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
  626. package/dist/frontend/lowering/containers/collection-methods.js +54 -25
  627. package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
  628. package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
  629. package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
  630. package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
  631. package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
  632. package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
  633. package/dist/frontend/lowering/containers/for-of.js +19 -19
  634. package/dist/frontend/lowering/containers/for-of.js.map +1 -1
  635. package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
  636. package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
  637. package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
  638. package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
  639. package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
  640. package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
  641. package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
  642. package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
  643. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
  644. package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
  645. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  646. package/dist/frontend/lowering/containers/string-replacement.js +1 -1
  647. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
  648. package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
  649. package/dist/frontend/lowering/cycle-initialization.js +39 -0
  650. package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
  651. package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
  652. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
  653. package/dist/frontend/lowering/devirtualize.d.ts +1 -1
  654. package/dist/frontend/lowering/devirtualize.js +27 -7
  655. package/dist/frontend/lowering/devirtualize.js.map +1 -1
  656. package/dist/frontend/lowering/divergences.d.ts +0 -5
  657. package/dist/frontend/lowering/divergences.js +62 -125
  658. package/dist/frontend/lowering/divergences.js.map +1 -1
  659. package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
  660. package/dist/frontend/lowering/dyn-streams.js +257 -0
  661. package/dist/frontend/lowering/dyn-streams.js.map +1 -0
  662. package/dist/frontend/lowering/error-methods.js +4 -1
  663. package/dist/frontend/lowering/error-methods.js.map +1 -1
  664. package/dist/frontend/lowering/error-name-order.d.ts +19 -0
  665. package/dist/frontend/lowering/error-name-order.js +93 -0
  666. package/dist/frontend/lowering/error-name-order.js.map +1 -0
  667. package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
  668. package/dist/frontend/lowering/expressions/array-literals.js +703 -0
  669. package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
  670. package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
  671. package/dist/frontend/lowering/expressions/binary.js +2483 -0
  672. package/dist/frontend/lowering/expressions/binary.js.map +1 -0
  673. package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
  674. package/dist/frontend/lowering/expressions/element-access.js +1797 -0
  675. package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
  676. package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
  677. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
  678. package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
  679. package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
  680. package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
  681. package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
  682. package/dist/frontend/lowering/expressions/identifiers.js +830 -0
  683. package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
  684. package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
  685. package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
  686. package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
  687. package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
  688. package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
  689. package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
  690. package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
  691. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
  692. package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
  693. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  694. package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
  695. package/dist/frontend/lowering/expressions/object-literals.js +253 -85
  696. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  697. package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
  698. package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
  699. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  700. package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
  701. package/dist/frontend/lowering/expressions/property-access.js +3544 -0
  702. package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
  703. package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
  704. package/dist/frontend/lowering/expressions/relational.js +1679 -0
  705. package/dist/frontend/lowering/expressions/relational.js.map +1 -0
  706. package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
  707. package/dist/frontend/lowering/expressions/typeof.js +538 -0
  708. package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
  709. package/dist/frontend/lowering/expressions/union-fields.js +1 -1
  710. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
  711. package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
  712. package/dist/frontend/lowering/expressions/updates.js +780 -0
  713. package/dist/frontend/lowering/expressions/updates.js.map +1 -0
  714. package/dist/frontend/lowering/function-context.d.ts +10 -0
  715. package/dist/frontend/lowering/function-context.js +11 -1
  716. package/dist/frontend/lowering/function-context.js.map +1 -1
  717. package/dist/frontend/lowering/function-returns.js +52 -28
  718. package/dist/frontend/lowering/function-returns.js.map +1 -1
  719. package/dist/frontend/lowering/general-streams.d.ts +25 -0
  720. package/dist/frontend/lowering/general-streams.js +108 -0
  721. package/dist/frontend/lowering/general-streams.js.map +1 -0
  722. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
  723. package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
  724. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  725. package/dist/frontend/lowering/generic-functions.d.ts +39 -0
  726. package/dist/frontend/lowering/generic-functions.js +393 -75
  727. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  728. package/dist/frontend/lowering/import-meta.js +2 -2
  729. package/dist/frontend/lowering/import-meta.js.map +1 -1
  730. package/dist/frontend/lowering/intern-tables.js +10 -9
  731. package/dist/frontend/lowering/intern-tables.js.map +1 -1
  732. package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
  733. package/dist/frontend/lowering/iterator-adapters.js +331 -3
  734. package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
  735. package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
  736. package/dist/frontend/lowering/js-class-fields.js +170 -0
  737. package/dist/frontend/lowering/js-class-fields.js.map +1 -0
  738. package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
  739. package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
  740. package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
  741. package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
  742. package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
  743. package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
  744. package/dist/frontend/lowering/json-require.d.ts +22 -0
  745. package/dist/frontend/lowering/json-require.js +131 -0
  746. package/dist/frontend/lowering/json-require.js.map +1 -0
  747. package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
  748. package/dist/frontend/lowering/key-order-witness.js +641 -0
  749. package/dist/frontend/lowering/key-order-witness.js.map +1 -0
  750. package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
  751. package/dist/frontend/lowering/key-order-witness.test.js +239 -0
  752. package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
  753. package/dist/frontend/lowering/lifetime-regions.js +7 -7
  754. package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
  755. package/dist/frontend/lowering/lower-assert.js +61 -60
  756. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  757. package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
  758. package/dist/frontend/lowering/lower-async-iteration.js +34 -6
  759. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  760. package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
  761. package/dist/frontend/lowering/lower-builtin-values.js +32 -3
  762. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  763. package/dist/frontend/lowering/lower-calls.js +1239 -442
  764. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  765. package/dist/frontend/lowering/lower-classes.d.ts +50 -3
  766. package/dist/frontend/lowering/lower-classes.js +1473 -468
  767. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  768. package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
  769. package/dist/frontend/lowering/lower-comptime.js +111 -13
  770. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  771. package/dist/frontend/lowering/lower-console.js +13 -11
  772. package/dist/frontend/lowering/lower-console.js.map +1 -1
  773. package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
  774. package/dist/frontend/lowering/lower-dgram.js +179 -8
  775. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  776. package/dist/frontend/lowering/lower-enums.js +113 -14
  777. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  778. package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
  779. package/dist/frontend/lowering/lower-event-emitter.js +258 -70
  780. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  781. package/dist/frontend/lowering/lower-event-target.js +2 -2
  782. package/dist/frontend/lowering/lower-event-target.js.map +1 -1
  783. package/dist/frontend/lowering/lower-expando.js +17 -13
  784. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  785. package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
  786. package/dist/frontend/lowering/lower-exprs.js +1481 -12489
  787. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  788. package/dist/frontend/lowering/lower-functions.js +68 -22
  789. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  790. package/dist/frontend/lowering/lower-generators.d.ts +6 -0
  791. package/dist/frontend/lowering/lower-generators.js +29 -16
  792. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  793. package/dist/frontend/lowering/lower-global-value.js +5 -1
  794. package/dist/frontend/lowering/lower-global-value.js.map +1 -1
  795. package/dist/frontend/lowering/lower-inspect.js +331 -96
  796. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  797. package/dist/frontend/lowering/lower-mixins.js +23 -20
  798. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  799. package/dist/frontend/lowering/lower-mock.d.ts +8 -1
  800. package/dist/frontend/lowering/lower-mock.js +185 -18
  801. package/dist/frontend/lowering/lower-mock.js.map +1 -1
  802. package/dist/frontend/lowering/lower-modules.js +267 -61
  803. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  804. package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
  805. package/dist/frontend/lowering/lower-namespaces.js +45 -33
  806. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  807. package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
  808. package/dist/frontend/lowering/lower-node-module.js +147 -14
  809. package/dist/frontend/lowering/lower-node-module.js.map +1 -1
  810. package/dist/frontend/lowering/lower-server.d.ts +6 -6
  811. package/dist/frontend/lowering/lower-server.js +488 -100
  812. package/dist/frontend/lowering/lower-server.js.map +1 -1
  813. package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
  814. package/dist/frontend/lowering/lower-stdlib.js +151 -109
  815. package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
  816. package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
  817. package/dist/frontend/lowering/lower-stmts.js +1541 -391
  818. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  819. package/dist/frontend/lowering/lower-stream.d.ts +3 -0
  820. package/dist/frontend/lowering/lower-stream.js +398 -56
  821. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  822. package/dist/frontend/lowering/lower-test.d.ts +3 -0
  823. package/dist/frontend/lowering/lower-test.js +437 -62
  824. package/dist/frontend/lowering/lower-test.js.map +1 -1
  825. package/dist/frontend/lowering/lower-timers.js +80 -32
  826. package/dist/frontend/lowering/lower-timers.js.map +1 -1
  827. package/dist/frontend/lowering/lower-url.js +1 -1
  828. package/dist/frontend/lowering/lower-url.js.map +1 -1
  829. package/dist/frontend/lowering/lowerer.d.ts +399 -26
  830. package/dist/frontend/lowering/lowerer.js +1910 -305
  831. package/dist/frontend/lowering/lowerer.js.map +1 -1
  832. package/dist/frontend/lowering/lowerer.test.js +10 -4
  833. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  834. package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
  835. package/dist/frontend/lowering/maybe-promise.js +249 -0
  836. package/dist/frontend/lowering/maybe-promise.js.map +1 -0
  837. package/dist/frontend/lowering/module-member-this.d.ts +3 -0
  838. package/dist/frontend/lowering/module-member-this.js +262 -0
  839. package/dist/frontend/lowering/module-member-this.js.map +1 -0
  840. package/dist/frontend/lowering/module-namespace-elements.js +1 -1
  841. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
  842. package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
  843. package/dist/frontend/lowering/nan-coded-reads.js +45 -32
  844. package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
  845. package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
  846. package/dist/frontend/lowering/narrowing-stability.js +104 -32
  847. package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
  848. package/dist/frontend/lowering/native-ffi.js +11 -11
  849. package/dist/frontend/lowering/native-ffi.js.map +1 -1
  850. package/dist/frontend/lowering/object-factory-new.js +6 -8
  851. package/dist/frontend/lowering/object-factory-new.js.map +1 -1
  852. package/dist/frontend/lowering/private-brands.d.ts +46 -0
  853. package/dist/frontend/lowering/private-brands.js +265 -0
  854. package/dist/frontend/lowering/private-brands.js.map +1 -0
  855. package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
  856. package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
  857. package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
  858. package/dist/frontend/lowering/require-initialization.d.ts +32 -0
  859. package/dist/frontend/lowering/require-initialization.js +246 -0
  860. package/dist/frontend/lowering/require-initialization.js.map +1 -0
  861. package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
  862. package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
  863. package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
  864. package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
  865. package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
  866. package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
  867. package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
  868. package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
  869. package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
  870. package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
  871. package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
  872. package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
  873. package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
  874. package/dist/frontend/lowering/runtime-optional-records.js +205 -32
  875. package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
  876. package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
  877. package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
  878. package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
  879. package/dist/frontend/lowering/split-consumers.js +4 -4
  880. package/dist/frontend/lowering/split-consumers.js.map +1 -1
  881. package/dist/frontend/lowering/static-function-names.d.ts +28 -0
  882. package/dist/frontend/lowering/static-function-names.js +212 -0
  883. package/dist/frontend/lowering/static-function-names.js.map +1 -0
  884. package/dist/frontend/lowering/static-this.js +6 -6
  885. package/dist/frontend/lowering/static-this.js.map +1 -1
  886. package/dist/frontend/lowering/strict-mode.d.ts +5 -0
  887. package/dist/frontend/lowering/strict-mode.js +31 -0
  888. package/dist/frontend/lowering/strict-mode.js.map +1 -0
  889. package/dist/frontend/lowering/string-index-bounds.js +10 -10
  890. package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
  891. package/dist/frontend/lowering/string-index.d.ts +12 -0
  892. package/dist/frontend/lowering/string-index.js +72 -1
  893. package/dist/frontend/lowering/string-index.js.map +1 -1
  894. package/dist/frontend/lowering/surfaces.d.ts +12 -3
  895. package/dist/frontend/lowering/surfaces.js +252 -41
  896. package/dist/frontend/lowering/surfaces.js.map +1 -1
  897. package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
  898. package/dist/frontend/lowering/symbol-fields.js +204 -36
  899. package/dist/frontend/lowering/symbol-fields.js.map +1 -1
  900. package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
  901. package/dist/frontend/lowering/symbol-methods.js +24 -6
  902. package/dist/frontend/lowering/symbol-methods.js.map +1 -1
  903. package/dist/frontend/lowering/thread-slots.d.ts +13 -0
  904. package/dist/frontend/lowering/thread-slots.js +208 -0
  905. package/dist/frontend/lowering/thread-slots.js.map +1 -0
  906. package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
  907. package/dist/frontend/lowering/typed-arguments.js +472 -0
  908. package/dist/frontend/lowering/typed-arguments.js.map +1 -0
  909. package/dist/frontend/lowering/union-retag.d.ts +8 -0
  910. package/dist/frontend/lowering/union-retag.js +27 -0
  911. package/dist/frontend/lowering/union-retag.js.map +1 -1
  912. package/dist/frontend/lowering/union-retag.test.js +24 -1
  913. package/dist/frontend/lowering/union-retag.test.js.map +1 -1
  914. package/dist/frontend/lowering/var-hoisting.js +6 -6
  915. package/dist/frontend/lowering/var-hoisting.js.map +1 -1
  916. package/dist/frontend/lowering/width-lift.d.ts +4 -0
  917. package/dist/frontend/mock-shapes.js +13 -6
  918. package/dist/frontend/mock-shapes.js.map +1 -1
  919. package/dist/frontend/module-source-candidates.js +1 -1
  920. package/dist/frontend/module-source-candidates.js.map +1 -1
  921. package/dist/frontend/module-source-candidates.test.js +2 -1
  922. package/dist/frontend/module-source-candidates.test.js.map +1 -1
  923. package/dist/frontend/module-syntax.js +8 -8
  924. package/dist/frontend/module-syntax.js.map +1 -1
  925. package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
  926. package/dist/frontend/npm-static-bundled-chunks.js +810 -0
  927. package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
  928. package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
  929. package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
  930. package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
  931. package/dist/frontend/npm-static-bundled-cjs.js +24 -23
  932. package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
  933. package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
  934. package/dist/frontend/npm-static-bundled-esm.js +768 -0
  935. package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
  936. package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
  937. package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
  938. package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
  939. package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
  940. package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
  941. package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
  942. package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
  943. package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
  944. package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
  945. package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
  946. package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
  947. package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
  948. package/dist/frontend/npm-static-declaration-syntax.js +102 -101
  949. package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
  950. package/dist/frontend/npm-static-prune.js +36 -24
  951. package/dist/frontend/npm-static-prune.js.map +1 -1
  952. package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
  953. package/dist/frontend/npm-static-rewrite-host.js +14 -3
  954. package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
  955. package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
  956. package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
  957. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
  958. package/dist/frontend/npm-static-subtyping.js +7 -9
  959. package/dist/frontend/npm-static-subtyping.js.map +1 -1
  960. package/dist/frontend/npm-static.d.ts +17 -1
  961. package/dist/frontend/npm-static.js +167 -16
  962. package/dist/frontend/npm-static.js.map +1 -1
  963. package/dist/frontend/npm-static.test.js +22 -1
  964. package/dist/frontend/npm-static.test.js.map +1 -1
  965. package/dist/frontend/pipeline.js +164 -26
  966. package/dist/frontend/pipeline.js.map +1 -1
  967. package/dist/frontend/pipeline.test.js +22 -1
  968. package/dist/frontend/pipeline.test.js.map +1 -1
  969. package/dist/frontend/program-analysis.d.ts +6 -1
  970. package/dist/frontend/program-analysis.js +7 -0
  971. package/dist/frontend/program-analysis.js.map +1 -1
  972. package/dist/frontend/program.d.ts +92 -2
  973. package/dist/frontend/program.js +1557 -255
  974. package/dist/frontend/program.js.map +1 -1
  975. package/dist/frontend/program.test.js +76 -6
  976. package/dist/frontend/program.test.js.map +1 -1
  977. package/dist/frontend/resolve.js +36 -2
  978. package/dist/frontend/resolve.js.map +1 -1
  979. package/dist/frontend/resolve.test.js +49 -0
  980. package/dist/frontend/resolve.test.js.map +1 -1
  981. package/dist/frontend/services.d.ts +20 -1
  982. package/dist/frontend/services.js +40 -3
  983. package/dist/frontend/services.js.map +1 -1
  984. package/dist/frontend/services.test.js +2 -1
  985. package/dist/frontend/services.test.js.map +1 -1
  986. package/dist/frontend/threads-import.js +1 -1
  987. package/dist/frontend/threads-import.js.map +1 -1
  988. package/dist/frontend/tier-analysis.d.ts +71 -0
  989. package/dist/frontend/tier-analysis.js +522 -0
  990. package/dist/frontend/tier-analysis.js.map +1 -0
  991. package/dist/frontend/ts7/api-conformance.d.ts +234 -0
  992. package/dist/frontend/ts7/api-conformance.js +7 -0
  993. package/dist/frontend/ts7/api-conformance.js.map +1 -0
  994. package/dist/frontend/ts7/ast-guards.generated.js +2 -1
  995. package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
  996. package/dist/frontend/ts7/ast-node.d.ts +47 -25
  997. package/dist/frontend/ts7/ast-node.js +64 -18
  998. package/dist/frontend/ts7/ast-node.js.map +1 -1
  999. package/dist/frontend/ts7/ast-node.test.js +36 -12
  1000. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  1001. package/dist/frontend/ts7/ast-types.d.ts +10 -3
  1002. package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
  1003. package/dist/frontend/ts7/ast.d.ts +1 -0
  1004. package/dist/frontend/ts7/ast.js +3 -2
  1005. package/dist/frontend/ts7/ast.js.map +1 -1
  1006. package/dist/frontend/ts7/checker-backend.d.ts +23 -0
  1007. package/dist/frontend/ts7/checker-backend.js +88 -0
  1008. package/dist/frontend/ts7/checker-backend.js.map +1 -0
  1009. package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
  1010. package/dist/frontend/ts7/checker-backend.test.js +63 -0
  1011. package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
  1012. package/dist/frontend/ts7/checker-cache.d.ts +0 -3
  1013. package/dist/frontend/ts7/checker-cache.js +0 -6
  1014. package/dist/frontend/ts7/checker-cache.js.map +1 -1
  1015. package/dist/frontend/ts7/checker.d.ts +18 -11
  1016. package/dist/frontend/ts7/checker.js +42 -55
  1017. package/dist/frontend/ts7/checker.js.map +1 -1
  1018. package/dist/frontend/ts7/checker.test.js +10 -7
  1019. package/dist/frontend/ts7/checker.test.js.map +1 -1
  1020. package/dist/frontend/ts7/diagnostic.d.ts +19 -0
  1021. package/dist/frontend/ts7/diagnostic.js +22 -0
  1022. package/dist/frontend/ts7/diagnostic.js.map +1 -0
  1023. package/dist/frontend/ts7/node-functions.d.ts +8 -0
  1024. package/dist/frontend/ts7/node-functions.js +18 -0
  1025. package/dist/frontend/ts7/node-functions.js.map +1 -0
  1026. package/dist/frontend/ts7/program-host.d.ts +5 -1
  1027. package/dist/frontend/ts7/program-host.js +12 -0
  1028. package/dist/frontend/ts7/program-host.js.map +1 -1
  1029. package/dist/frontend/ts7/rpc-api.d.ts +5 -1
  1030. package/dist/frontend/ts7/rpc-api.js +8 -1
  1031. package/dist/frontend/ts7/rpc-api.js.map +1 -1
  1032. package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
  1033. package/dist/frontend/ts7/semantic-checker.js +26 -8
  1034. package/dist/frontend/ts7/semantic-checker.js.map +1 -1
  1035. package/dist/frontend/ts7/semantic-checker.test.js +12 -9
  1036. package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
  1037. package/dist/frontend/ts7/semantic-model.d.ts +54 -24
  1038. package/dist/frontend/ts7/semantic-model.js +88 -16
  1039. package/dist/frontend/ts7/semantic-model.js.map +1 -1
  1040. package/dist/frontend/ts7/semantic-model.test.js +4 -4
  1041. package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
  1042. package/dist/frontend/ts7/semantic-types.d.ts +7 -3
  1043. package/dist/frontend/ts7/semantic-types.js +1 -1
  1044. package/dist/frontend/ts7/semantic-types.js.map +1 -1
  1045. package/dist/frontend/ts7/session.d.ts +11 -11
  1046. package/dist/frontend/ts7/session.js +8 -5
  1047. package/dist/frontend/ts7/session.js.map +1 -1
  1048. package/dist/frontend/ts7/session.test.js +9 -5
  1049. package/dist/frontend/ts7/session.test.js.map +1 -1
  1050. package/dist/frontend/ts7/source-parser.d.ts +6 -2
  1051. package/dist/frontend/ts7/source-parser.js +24 -3
  1052. package/dist/frontend/ts7/source-parser.js.map +1 -1
  1053. package/dist/frontend/ts7/source-parser.test.js +38 -17
  1054. package/dist/frontend/ts7/source-parser.test.js.map +1 -1
  1055. package/dist/frontend/type-mapper.d.ts +122 -2
  1056. package/dist/frontend/type-mapper.js +2545 -719
  1057. package/dist/frontend/type-mapper.js.map +1 -1
  1058. package/dist/frontend/type-only-imports.d.ts +28 -0
  1059. package/dist/frontend/type-only-imports.js +122 -0
  1060. package/dist/frontend/type-only-imports.js.map +1 -0
  1061. package/dist/frontend/worker-target.js +8 -8
  1062. package/dist/frontend/worker-target.js.map +1 -1
  1063. package/dist/index.d.ts +3 -1
  1064. package/dist/index.js +29 -2
  1065. package/dist/index.js.map +1 -1
  1066. package/dist/ir/analysis.js +4 -2
  1067. package/dist/ir/analysis.js.map +1 -1
  1068. package/dist/ir/api.d.ts +1 -1
  1069. package/dist/ir/api.js +1 -1
  1070. package/dist/ir/api.js.map +1 -1
  1071. package/dist/ir/array-length-stability.d.ts +30 -0
  1072. package/dist/ir/array-length-stability.js +236 -0
  1073. package/dist/ir/array-length-stability.js.map +1 -0
  1074. package/dist/ir/array-length-stability.test.d.ts +1 -0
  1075. package/dist/ir/array-length-stability.test.js +113 -0
  1076. package/dist/ir/array-length-stability.test.js.map +1 -0
  1077. package/dist/ir/build.d.ts +2 -2
  1078. package/dist/ir/build.js +1 -1
  1079. package/dist/ir/build.js.map +1 -1
  1080. package/dist/ir/builtin-effects.js +103 -0
  1081. package/dist/ir/builtin-effects.js.map +1 -1
  1082. package/dist/ir/builtin-signatures.d.ts +1 -1
  1083. package/dist/ir/builtin-signatures.js +494 -25
  1084. package/dist/ir/builtin-signatures.js.map +1 -1
  1085. package/dist/ir/byte-numbers.js +3 -0
  1086. package/dist/ir/byte-numbers.js.map +1 -1
  1087. package/dist/ir/callback-specialization.d.ts +37 -0
  1088. package/dist/ir/callback-specialization.js +459 -0
  1089. package/dist/ir/callback-specialization.js.map +1 -0
  1090. package/dist/ir/callback-specialization.test.d.ts +1 -0
  1091. package/dist/ir/callback-specialization.test.js +208 -0
  1092. package/dist/ir/callback-specialization.test.js.map +1 -0
  1093. package/dist/ir/capture-values.d.ts +0 -1
  1094. package/dist/ir/capture-values.js +51 -40
  1095. package/dist/ir/capture-values.js.map +1 -1
  1096. package/dist/ir/constant-globals.test.js +1 -1
  1097. package/dist/ir/constant-tables.test.js +1 -1
  1098. package/dist/ir/field-values.test.js +1 -1
  1099. package/dist/ir/final-fields.test.js +1 -1
  1100. package/dist/ir/function-references.test.js +9 -1
  1101. package/dist/ir/function-references.test.js.map +1 -1
  1102. package/dist/ir/init-only-globals.test.js +1 -1
  1103. package/dist/ir/initializer-bindings.test.js +1 -1
  1104. package/dist/ir/int32-slots.d.ts +14 -0
  1105. package/dist/ir/int32-slots.js +97 -14
  1106. package/dist/ir/int32-slots.js.map +1 -1
  1107. package/dist/ir/int32-slots.test.js +1 -1
  1108. package/dist/ir/integer-loop-facts.d.ts +2 -0
  1109. package/dist/ir/integer-loop-facts.js +24 -3
  1110. package/dist/ir/integer-loop-facts.js.map +1 -1
  1111. package/dist/ir/integer-loops.d.ts +1 -1
  1112. package/dist/ir/integer-loops.js +39 -9
  1113. package/dist/ir/integer-loops.js.map +1 -1
  1114. package/dist/ir/integer-loops.test.js +104 -0
  1115. package/dist/ir/integer-loops.test.js.map +1 -1
  1116. package/dist/ir/integer-ranges.d.ts +3 -0
  1117. package/dist/ir/integer-ranges.js +3 -1
  1118. package/dist/ir/integer-ranges.js.map +1 -1
  1119. package/dist/ir/integer-ranges.test.js +82 -1
  1120. package/dist/ir/integer-ranges.test.js.map +1 -1
  1121. package/dist/ir/intrinsic-signatures.js +6 -0
  1122. package/dist/ir/intrinsic-signatures.js.map +1 -1
  1123. package/dist/ir/ir.d.ts +221 -58
  1124. package/dist/ir/ir.js +119 -12
  1125. package/dist/ir/ir.js.map +1 -1
  1126. package/dist/ir/ir.test.js +10 -0
  1127. package/dist/ir/ir.test.js.map +1 -1
  1128. package/dist/ir/jsval.d.ts +8 -0
  1129. package/dist/ir/jsval.js +365 -0
  1130. package/dist/ir/jsval.js.map +1 -0
  1131. package/dist/ir/jsval.test.d.ts +1 -0
  1132. package/dist/ir/jsval.test.js +239 -0
  1133. package/dist/ir/jsval.test.js.map +1 -0
  1134. package/dist/ir/runtime-features.d.ts +148 -33
  1135. package/dist/ir/runtime-features.js +629 -386
  1136. package/dist/ir/runtime-features.js.map +1 -1
  1137. package/dist/ir/scalar-records.test.js +1 -1
  1138. package/dist/ir/self-captures.d.ts +33 -0
  1139. package/dist/ir/self-captures.js +245 -0
  1140. package/dist/ir/self-captures.js.map +1 -0
  1141. package/dist/ir/self-captures.test.d.ts +1 -0
  1142. package/dist/ir/self-captures.test.js +135 -0
  1143. package/dist/ir/self-captures.test.js.map +1 -0
  1144. package/dist/ir/serialize.d.ts +1 -1
  1145. package/dist/ir/serialize.js +7 -4
  1146. package/dist/ir/serialize.js.map +1 -1
  1147. package/dist/ir/tiers.d.ts +26 -0
  1148. package/dist/ir/tiers.js +101 -0
  1149. package/dist/ir/tiers.js.map +1 -0
  1150. package/dist/ir/tiers.test.d.ts +1 -0
  1151. package/dist/ir/tiers.test.js +140 -0
  1152. package/dist/ir/tiers.test.js.map +1 -0
  1153. package/dist/ir/traverse.js +103 -94
  1154. package/dist/ir/traverse.js.map +1 -1
  1155. package/dist/ir/traverse.test.js +33 -30
  1156. package/dist/ir/traverse.test.js.map +1 -1
  1157. package/dist/ir/unshare.js +65 -3
  1158. package/dist/ir/unshare.js.map +1 -1
  1159. package/dist/ir/unshare.test.js +1 -1
  1160. package/dist/ir/validate.js +175 -68
  1161. package/dist/ir/validate.js.map +1 -1
  1162. package/dist/ir/validate.test.js +26 -9
  1163. package/dist/ir/validate.test.js.map +1 -1
  1164. package/dist/library/fence-eval.test.js +1 -1
  1165. package/dist/library/int-infer.test.js +4 -4
  1166. package/dist/library/ir-policy.js +13 -0
  1167. package/dist/library/ir-policy.js.map +1 -1
  1168. package/dist/library/library-cache.d.ts +1 -0
  1169. package/dist/library/library-cache.js.map +1 -1
  1170. package/dist/library/library-cache.test.js +5 -5
  1171. package/dist/library/library-profile.d.ts +4 -4
  1172. package/dist/library/library-profile.js +35 -7
  1173. package/dist/library/library-profile.js.map +1 -1
  1174. package/dist/library/prepare.js +13 -1
  1175. package/dist/library/prepare.js.map +1 -1
  1176. package/dist/native/cli.js +5 -0
  1177. package/dist/native/cli.js.map +1 -1
  1178. package/dist/native/compiler.js +2 -2
  1179. package/dist/native/compiler.js.map +1 -1
  1180. package/dist/native/compiler.test.js +2 -2
  1181. package/dist/native/prepare.js +7 -0
  1182. package/dist/native/prepare.js.map +1 -1
  1183. package/dist/native/sanitizer.test.js +12 -0
  1184. package/dist/native/sanitizer.test.js.map +1 -1
  1185. package/dist/native/toolchain.d.ts +2 -0
  1186. package/dist/native/toolchain.js +10 -1
  1187. package/dist/native/toolchain.js.map +1 -1
  1188. package/dist/native/toolchain.test.js +39 -1
  1189. package/dist/native/toolchain.test.js.map +1 -1
  1190. package/dist/startup-cache.d.ts +1 -0
  1191. package/dist/startup-cache.js +1 -0
  1192. package/dist/startup-cache.js.map +1 -1
  1193. package/dist/wasm/base64.d.ts +5 -0
  1194. package/dist/wasm/base64.js +62 -0
  1195. package/dist/wasm/base64.js.map +1 -0
  1196. package/dist/wasm/binary.d.ts +36 -0
  1197. package/dist/wasm/binary.js +1976 -0
  1198. package/dist/wasm/binary.js.map +1 -0
  1199. package/dist/wasm/binary.test.d.ts +1 -0
  1200. package/dist/wasm/binary.test.js +190 -0
  1201. package/dist/wasm/binary.test.js.map +1 -0
  1202. package/dist/wasm/discover.d.ts +38 -0
  1203. package/dist/wasm/discover.js +377 -0
  1204. package/dist/wasm/discover.js.map +1 -0
  1205. package/dist/wasm/discover.test.d.ts +1 -0
  1206. package/dist/wasm/discover.test.js +24 -0
  1207. package/dist/wasm/discover.test.js.map +1 -0
  1208. package/dist/wasm/module.d.ts +151 -0
  1209. package/dist/wasm/module.js +575 -0
  1210. package/dist/wasm/module.js.map +1 -0
  1211. package/dist/wasm/translate.d.ts +48 -0
  1212. package/dist/wasm/translate.js +2129 -0
  1213. package/dist/wasm/translate.js.map +1 -0
  1214. package/dist/wasm/translate.test.d.ts +1 -0
  1215. package/dist/wasm/translate.test.js +207 -0
  1216. package/dist/wasm/translate.test.js.map +1 -0
  1217. package/package.json +21 -20
  1218. package/surface-manifest.json +303 -19
@@ -2,7 +2,7 @@ import { InternalCompilerError } from "../errors.js";
2
2
  import { mockCallRecordType, mockContextType } from "./mock-shapes.js";
3
3
  import * as ts from "./ts7/adapter.js";
4
4
  import { bodyReadsArguments } from "./arguments-usage.js";
5
- import { BYTES_ELEMENT_NAME, arrayOf, BOOL, bytesOf, canConvertToDyn, CHILD_T, CRYPTOHASH_T, CRYPTOHMAC_T, DATE_T, DYN, F64, funcOf, isSupportedArrayElem, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, mapOf, NULL_T, PROCSTREAM_T, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, ZLIB_STREAM_MODES, setOf, STRING, SYMBOL_T, typeEquals, typeKey, unionContainerArmsOk, UNDEFINED_T, VOID, } from "../ir/ir.js";
5
+ import { BYTES_ELEMENT_NAME, arrayOf, isDynTypedRefType, BOOL, bytesOf, canConvertToDyn, canDynCheckTo, CHILD_T, CRYPTOHASH_T, CRYPTOHMAC_T, DATE_T, DYN, F64, funcOf, isSupportedArrayElem, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, mapOf, NULL_T, PROCSTREAM_T, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, ZLIB_STREAM_MODES, setOf, STRING, SYMBOL_T, typeEquals, typeKey, maybePromiseUnionArmsOk, unionContainerArmsOk, UNDEFINED_T, VOID, } from "../ir/ir.js";
6
6
  import { BIGINT_T } from "../ir/ir.js";
7
7
  import { literalValues } from "./literal-values.js";
8
8
  import { remapUnionDiscriminant } from "./union-discriminants.js";
@@ -21,7 +21,7 @@ function runtimeParameterCount(parameters) {
21
21
  /** Empty JS object inference describes no fixed layout. Keep these values
22
22
  * in checked storage across fields, parameters and function signatures. */
23
23
  export function jsOpenObjectType(decl, type, shapes, unions) {
24
- if (!decl || !isJsSourceFile(decl.getSourceFile()))
24
+ if (!decl || !isJsSourceFile(ts.getSourceFileOfNode(decl)))
25
25
  return type;
26
26
  const arms = type.kind === "union" ? unions.get(type.unionId)?.arms : [type];
27
27
  const present = arms?.filter((arm) => arm.kind !== "undefinedT");
@@ -67,6 +67,25 @@ export function jsOpenObjectType(decl, type, shapes, unions) {
67
67
  ? DYN
68
68
  : type;
69
69
  }
70
+ /** The modules whose RequestOptions interface maps to the checked dynamic. */
71
+ const HTTP_REQUEST_OPTION_MODULES = new Set([
72
+ "http",
73
+ "node:http",
74
+ "https",
75
+ "node:https",
76
+ ]);
77
+ /** The WebCrypto interfaces whose values are checked-dynamic: the crypto
78
+ * global, SubtleCrypto, CryptoKey handles and the algorithm dictionaries
79
+ * (scr_webcrypto.c). */
80
+ export const WEBCRYPTO_DYN_TYPES = new Set([
81
+ "Crypto",
82
+ "SubtleCrypto",
83
+ "CryptoKey",
84
+ "Algorithm",
85
+ "KeyAlgorithm",
86
+ "HmacImportParams",
87
+ "HmacKeyAlgorithm",
88
+ ]);
70
89
  export const FETCH_AMBIENT_TYPES = [
71
90
  "Response",
72
91
  "Request",
@@ -74,6 +93,7 @@ export const FETCH_AMBIENT_TYPES = [
74
93
  "RequestInit",
75
94
  "Event",
76
95
  "CustomEvent",
96
+ "MessageEvent",
77
97
  "EventTarget",
78
98
  "AddEventListenerOptions",
79
99
  "EventListenerOptions",
@@ -232,7 +252,7 @@ export class ShapeRegistry {
232
252
  comparePriority(previous, this.currentDeclaredOrderPriority) <= 0) {
233
253
  return;
234
254
  }
235
- shape.declaredOrder = declaredOrder;
255
+ shape.declaredOrder = this.withExtendedNames(shape.id, declaredOrder);
236
256
  this.declaredOrderPriority.set(shape.id, this.currentDeclaredOrderPriority);
237
257
  }
238
258
  /** Mutable generic-instance ranks settle only after reachability closes.
@@ -250,7 +270,7 @@ export class ShapeRegistry {
250
270
  const shape = this.byId.get(shapeId);
251
271
  if (!shape)
252
272
  continue;
253
- shape.declaredOrder = best.order;
273
+ shape.declaredOrder = this.withExtendedNames(shapeId, best.order);
254
274
  this.declaredOrderPriority.set(shapeId, best.priority);
255
275
  }
256
276
  for (const finalize of this.derivedDeclaredOrderFinalizers)
@@ -274,7 +294,7 @@ export class ShapeRegistry {
274
294
  return;
275
295
  const next = order();
276
296
  if (next !== undefined)
277
- shape.declaredOrder = next;
297
+ shape.declaredOrder = this.withExtendedNames(shape.id, next);
278
298
  };
279
299
  }
280
300
  /** The shape id a back-reference to an in-progress type resolves to:
@@ -367,6 +387,52 @@ export class ShapeRegistry {
367
387
  get(shapeId) {
368
388
  return this.byId.get(shapeId);
369
389
  }
390
+ /** Names extendShape added to a shape, which every key-order table the
391
+ * shape adopts lists after its declared names. */
392
+ extendedNames = new Map();
393
+ /** The members extendShape attached to a shape (empty for most). */
394
+ attachedNames(shapeId) {
395
+ return this.extendedNames.get(shapeId) ?? [];
396
+ }
397
+ withExtendedNames(shapeId, order) {
398
+ const extra = this.extendedNames.get(shapeId);
399
+ if (!extra)
400
+ return order;
401
+ const missing = extra.filter((name) => !order.includes(name));
402
+ return missing.length === 0 ? order : [...order, ...missing];
403
+ }
404
+ /** Adds optional fields to an interned shape in place: members a type
405
+ * assertion attaches to the shape's values (`r as R & { tag: string }`
406
+ * followed by `view.tag = ...`; see assertion-members.ts). Every value
407
+ * of the shape holds them absent until a write through such a view, so
408
+ * the shape keeps its id, both structural keys resolve to it, and its
409
+ * key-order table lists the new names after the declared ones. Runs
410
+ * before any body lowers; existing layouts change, so the revision
411
+ * advances like a closing recursive placeholder. */
412
+ extendShape(shapeId, extra) {
413
+ const shape = this.byId.get(shapeId);
414
+ if (!shape || shape.tuple || extra.length === 0)
415
+ return;
416
+ const fresh = extra.filter((f) => !shape.fields.some((x) => x.name === f.name));
417
+ if (fresh.length === 0)
418
+ return;
419
+ shape.fields = [...shape.fields, ...fresh].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
420
+ this.extendedNames.set(shapeId, [
421
+ ...(this.extendedNames.get(shapeId) ?? []),
422
+ ...fresh.map((f) => f.name),
423
+ ]);
424
+ if (shape.declaredOrder)
425
+ shape.declaredOrder = this.withExtendedNames(shapeId, shape.declaredOrder);
426
+ const candidates = this.declaredOrderCandidates.get(shapeId);
427
+ if (candidates) {
428
+ for (const c of candidates)
429
+ c.order = this.withExtendedNames(shapeId, c.order);
430
+ }
431
+ this.revision++;
432
+ const key = this.keyOf(shape.fields, false, shape.indexValue);
433
+ if (!this.byKey.has(key))
434
+ this.byKey.set(key, shapeId);
435
+ }
370
436
  }
371
437
  /** The frontend's union interner — mirrors ShapeRegistry. A union's
372
438
  * canonical identity includes its typeKey-sorted arms and literal
@@ -527,6 +593,7 @@ export function formatIrType(t, shapes, unions, seen = new Set()) {
527
593
  case "bool":
528
594
  return append("boolean");
529
595
  case "dyn":
596
+ case "jsval":
530
597
  return append("unknown");
531
598
  case "caught":
532
599
  // What tsc calls the binding; the fence messages carry the real story.
@@ -793,7 +860,7 @@ function isDeclaredInAmbientModule(d, name) {
793
860
  /** True when the declaration's nearest enclosing namespace is `name`
794
861
  * (`declare global { namespace NodeJS { ... } }` — the NodeJS-global
795
862
  * interfaces @types/node declares outside any ambient module). */
796
- function isDeclaredInAmbientNamespace(d, name) {
863
+ export function isDeclaredInAmbientNamespace(d, name) {
797
864
  let node = d.parent;
798
865
  while (node) {
799
866
  if (ts.isModuleDeclaration(node) && ts.isIdentifier(node.name)) {
@@ -803,6 +870,39 @@ function isDeclaredInAmbientNamespace(d, name) {
803
870
  }
804
871
  return false;
805
872
  }
873
+ /** Whether `type` is one of the stream spellings the general stream
874
+ * representation (TypeMapperCtx.generalNodeStreams) maps differently:
875
+ * NodeJS.ReadableStream / NodeJS.WritableStream, @types/node's
876
+ * stream.Readable / stream.Writable, or the fallback declarations'
877
+ * ChildStdin. */
878
+ export function isGeneralNodeStreamInterface(type, ctx) {
879
+ const psym = type.getSymbol() ?? type.getAliasSymbol();
880
+ if (psym === undefined)
881
+ return false;
882
+ return psym.declarations.some((d) => {
883
+ if (!(ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)))
884
+ return false;
885
+ if (!ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
886
+ return false;
887
+ if (ts.symbolName(psym) === "ReadableStream" || ts.symbolName(psym) === "WritableStream")
888
+ return ts.isInterfaceDeclaration(d) && isDeclaredInAmbientNamespace(d, "NodeJS");
889
+ if (ts.symbolName(psym) === "ChildStdin")
890
+ return isDeclaredInAmbientModule(d, "child_process");
891
+ return ((ts.symbolName(psym) === "Readable" || ts.symbolName(psym) === "Writable") &&
892
+ isNodeTypesPath(ts.getSourceFileOfNode(d).fileName) &&
893
+ isDeclaredInAmbientModule(d, "stream"));
894
+ });
895
+ }
896
+ /** A type declared in the shipped WebAssembly namespace (scriptc.d.ts):
897
+ * its modules, instances, memories, tables, globals, error classes and the
898
+ * Exports/Imports records. */
899
+ export function isWebAssemblyType(type, ctx) {
900
+ const symbol = type.getAliasSymbol() ?? type.getSymbol();
901
+ if (!symbol)
902
+ return false;
903
+ return symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
904
+ isDeclaredInAmbientNamespace(d, "WebAssembly"));
905
+ }
806
906
  /** True when a type contains a record anywhere (the trigger for the
807
907
  * shape-mismatch diagnostic SC2002 — non-record mismatches are tsc's or
808
908
  * the validator's business). */
@@ -928,8 +1028,8 @@ export function isLegacyUrlType(type, ctx) {
928
1028
  export function isLegacyUrlSymbol(symbol, ctx) {
929
1029
  if (!symbol)
930
1030
  return false;
931
- for (const d of ctx.checker.declarationsOf(symbol)) {
932
- if (!ctx.isStdlibFile(d.getSourceFile()))
1031
+ for (const d of symbol.declarations) {
1032
+ if (!ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
933
1033
  continue;
934
1034
  let family = false;
935
1035
  for (let n = d; n; n = n.parent) {
@@ -958,10 +1058,11 @@ export function isOsConstantsType(type, ctx) {
958
1058
  export function isOsConstantsSymbol(symbol, ctx, types = false) {
959
1059
  if (!symbol)
960
1060
  return false;
961
- for (const d of ctx.checker.declarationsOf(symbol)) {
1061
+ for (const d of symbol.declarations) {
962
1062
  const alias = types && ts.isTypeAliasDeclaration(d) && d.name.text === "SignalConstants";
963
1063
  const signals = !types && ts.isVariableDeclaration(d) && ts.isIdentifier(d.name) && d.name.text === "signals";
964
- if (!(alias || signals || ts.isModuleDeclaration(d)) || !ctx.isStdlibFile(d.getSourceFile()))
1064
+ if (!(alias || signals || ts.isModuleDeclaration(d)) ||
1065
+ !ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
965
1066
  continue;
966
1067
  let inConstants = ts.isModuleDeclaration(d) && d.name.text === "constants";
967
1068
  for (let n = d.parent; n; n = n.parent) {
@@ -981,26 +1082,147 @@ export function isOsConstantsSymbol(symbol, ctx, types = false) {
981
1082
  /** worker_threads' Worker and MessagePort: owned runtime handles that keep
982
1083
  * their live object representation (DYN) wherever they are stored. */
983
1084
  function isWorkerHandleSymbol(symbol, ctx) {
984
- return ((symbol?.name === "Worker" ||
985
- symbol?.name === "MessagePort" ||
986
- symbol?.name === "MessageChannel") &&
987
- ctx.checker
988
- .declarationsOf(symbol)
989
- .some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
990
- ctx.isStdlibFile(d.getSourceFile()) &&
1085
+ return (((symbol !== undefined && ts.symbolName(symbol) === "Worker") ||
1086
+ (symbol !== undefined && ts.symbolName(symbol) === "MessagePort") ||
1087
+ (symbol !== undefined && ts.symbolName(symbol) === "MessageChannel") ||
1088
+ (symbol !== undefined && ts.symbolName(symbol) === "BroadcastChannel")) &&
1089
+ symbol.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
1090
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
991
1091
  isDeclaredInAmbientModule(d, "worker_threads")));
992
1092
  }
993
1093
  /** The `{ message: any }` object type (or its union with undefined) that
994
1094
  * worker_threads declares as receiveMessageOnPort's result. */
1095
+ /** A union of dns lookup option bags with numbers and nullish values that
1096
+ * includes LookupAllOptions (whose `all: true` arm has no record form). */
1097
+ function isLookupOptionsUnion(type, ctx) {
1098
+ if (!type.isUnionType())
1099
+ return false;
1100
+ let all = false;
1101
+ for (const member of ts.constituentTypes(type)) {
1102
+ if (member.flags & (ts.TypeFlags.NumberLike | ts.TypeFlags.Null | ts.TypeFlags.Undefined))
1103
+ continue;
1104
+ const symbol = member.getSymbol();
1105
+ if (symbol === undefined ||
1106
+ !/^Lookup(One|All)?Options$/.test(ts.symbolName(symbol)) ||
1107
+ !symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
1108
+ return false;
1109
+ if (ts.symbolName(symbol) === "LookupAllOptions")
1110
+ all = true;
1111
+ }
1112
+ return all;
1113
+ }
1114
+ /** The binary and stream members of fetch's BodyInit (undici-types):
1115
+ * NodeJS.ArrayBufferView expands to the typed arrays and DataView. */
1116
+ const FETCH_BODY_MEMBERS = new Set([
1117
+ "ArrayBuffer",
1118
+ "SharedArrayBuffer",
1119
+ "AsyncIterable",
1120
+ "Iterable",
1121
+ "Blob",
1122
+ "FormData",
1123
+ "URLSearchParams",
1124
+ "ReadableStream",
1125
+ "DataView",
1126
+ "Buffer",
1127
+ "Int8Array",
1128
+ "Uint8Array",
1129
+ "Uint8ClampedArray",
1130
+ "Int16Array",
1131
+ "Uint16Array",
1132
+ "Int32Array",
1133
+ "Uint32Array",
1134
+ "Float16Array",
1135
+ "Float32Array",
1136
+ "Float64Array",
1137
+ "BigInt64Array",
1138
+ "BigUint64Array",
1139
+ ]);
1140
+ /** fetch's request body type, BodyInit, however TypeScript spells it
1141
+ * (`RequestInit["body"]`, `NonNullable<...>`, an optional member): a
1142
+ * union of strings, the stdlib binary and stream types and nullish
1143
+ * values that includes both FormData and URLSearchParams. Native fetch
1144
+ * reads such a body at run time, so it rides checked-dynamic storage. */
1145
+ function isFetchBodyUnion(type, ctx) {
1146
+ if (!type.isUnionType())
1147
+ return false;
1148
+ let formData = false;
1149
+ let searchParams = false;
1150
+ for (const member of ts.constituentTypes(type)) {
1151
+ if (member.flags & (ts.TypeFlags.StringLike | ts.TypeFlags.Null | ts.TypeFlags.Undefined))
1152
+ continue;
1153
+ const symbol = member.getSymbol();
1154
+ if (symbol === undefined ||
1155
+ !FETCH_BODY_MEMBERS.has(ts.symbolName(symbol)) ||
1156
+ !symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
1157
+ return false;
1158
+ if (ts.symbolName(symbol) === "FormData")
1159
+ formData = true;
1160
+ if (ts.symbolName(symbol) === "URLSearchParams")
1161
+ searchParams = true;
1162
+ }
1163
+ return formData && searchParams;
1164
+ }
1165
+ /** A mapped object type (Omit, Pick, Partial) whose members all come from
1166
+ * one stdlib interface that maps to the checked dynamic. */
1167
+ function isDynInterfaceSubset(type, ctx) {
1168
+ if (!(type.flags & ts.TypeFlags.Object) || type.isClassOrInterface())
1169
+ return false;
1170
+ const alias = type.getAliasSymbol();
1171
+ if (alias === undefined)
1172
+ return false;
1173
+ const props = ctx.checker.getPropertiesOfType(type);
1174
+ if (props.length === 0)
1175
+ return false;
1176
+ let owner;
1177
+ for (const prop of props) {
1178
+ const decl = prop.declarations[0];
1179
+ const parent = decl?.parent;
1180
+ if (parent === undefined ||
1181
+ !ts.isInterfaceDeclaration(parent) ||
1182
+ !ctx.isStdlibFile(ts.getSourceFileOfNode(parent)) ||
1183
+ (owner !== undefined && owner !== parent))
1184
+ return false;
1185
+ owner = parent;
1186
+ }
1187
+ return (owner !== undefined && mapType(ctx.checker.getTypeAtLocation(owner.name), ctx)?.kind === "dyn");
1188
+ }
1189
+ /** fetch's HeadersInit (undici-types): a union of the stdlib Headers
1190
+ * class with header-pair arrays and/or a header record, plus nullish
1191
+ * values. Native fetch reads it at run time like the init around it. */
1192
+ function isFetchHeadersUnion(type, ctx) {
1193
+ if (!type.isUnionType())
1194
+ return false;
1195
+ let headers = false;
1196
+ let other = false;
1197
+ for (const member of ts.constituentTypes(type)) {
1198
+ if (member.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined))
1199
+ continue;
1200
+ const symbol = member.getSymbol();
1201
+ if (symbol !== undefined &&
1202
+ ts.symbolName(symbol) === "Headers" &&
1203
+ symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1204
+ headers = true;
1205
+ continue;
1206
+ }
1207
+ const alias = ts.symbolNameOf(member.getAliasSymbol());
1208
+ if ((symbol !== undefined && ts.symbolName(symbol) === "Array") ||
1209
+ (symbol !== undefined && ts.symbolName(symbol) === "ReadonlyArray") ||
1210
+ alias === "Record" ||
1211
+ alias === "HeaderRecord") {
1212
+ other = true;
1213
+ continue;
1214
+ }
1215
+ return false;
1216
+ }
1217
+ return headers && other;
1218
+ }
995
1219
  function isReceiveMessageResult(type, ctx) {
996
1220
  const members = type.isUnionType() ? ts.constituentTypes(type) : [type];
997
1221
  let found = false;
998
1222
  for (const member of members) {
999
1223
  if (member.flags & ts.TypeFlags.Undefined)
1000
1224
  continue;
1001
- const decl = member.getSymbol()
1002
- ? ctx.checker.declarationsOf(member.getSymbol())[0]
1003
- : undefined;
1225
+ const decl = member.getSymbol() ? member.getSymbol().declarations[0] : undefined;
1004
1226
  let fn = decl?.parent;
1005
1227
  while (fn && ts.isUnionTypeNode(fn))
1006
1228
  fn = fn.parent;
@@ -1009,7 +1231,7 @@ function isReceiveMessageResult(type, ctx) {
1009
1231
  !fn ||
1010
1232
  !ts.isFunctionDeclaration(fn) ||
1011
1233
  fn.name?.text !== "receiveMessageOnPort" ||
1012
- !ctx.isStdlibFile(decl.getSourceFile()) ||
1234
+ !ctx.isStdlibFile(ts.getSourceFileOfNode(decl)) ||
1013
1235
  !isDeclaredInAmbientModule(fn, "worker_threads")) {
1014
1236
  return false;
1015
1237
  }
@@ -1037,6 +1259,57 @@ export function isWorkerHandleType(type, ctx) {
1037
1259
  }
1038
1260
  return handle;
1039
1261
  }
1262
+ /** The return annotation of an `async *` declaration spelled with the
1263
+ * protocol interfaces the generator object implements —
1264
+ * `AsyncIterator<T>`, `AsyncIterableIterator<T>` or `AsyncIterable<T>` (pi's
1265
+ * `async *[Symbol.asyncIterator](): AsyncIterator<T>`): the body always
1266
+ * produces an async generator, so the declaration maps exactly like an
1267
+ * `AsyncGenerator<T, TReturn, TNext>` annotation. Values of these types
1268
+ * elsewhere stay unmapped (they can hold any object implementing the
1269
+ * protocol). Null when the annotation is not one of them. */
1270
+ export function mapAsyncGeneratorAnnotation(type, ctx) {
1271
+ const { checker } = ctx;
1272
+ const symbol = type.getSymbol();
1273
+ if (!symbol ||
1274
+ !["AsyncIterator", "AsyncIterableIterator", "AsyncIterable"].includes(ts.symbolName(symbol)) ||
1275
+ !symbol.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
1276
+ return null;
1277
+ const args = checker.getTypeArguments(type);
1278
+ const channels = genChannels(args[0], args[1], args[2], ctx);
1279
+ if (!channels)
1280
+ return null;
1281
+ if (!genResultRecord(channels.yieldT, channels.retT, ctx.shapes, ctx.unions))
1282
+ return null;
1283
+ return { kind: "generator", async: true, ...channels };
1284
+ }
1285
+ /** The native fetch handles (Headers, Request, Response), optionally in
1286
+ * arrays or with null/undefined: checked-dynamic handles wherever they are
1287
+ * stored, like the worker handles above. */
1288
+ export function isFetchHandleType(type, ctx) {
1289
+ const members = type.isUnionType() ? ts.constituentTypes(type) : [type];
1290
+ let handle = false;
1291
+ for (const member of members) {
1292
+ if (member.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined))
1293
+ continue;
1294
+ if (ctx.checker.isArrayType(member)) {
1295
+ const element = ctx.checker.getTypeArguments(member)[0];
1296
+ if (element === undefined || !isFetchHandleType(element, ctx))
1297
+ return false;
1298
+ }
1299
+ else {
1300
+ const symbol = member.getSymbol();
1301
+ if (!symbol ||
1302
+ (ts.symbolName(symbol) !== "Headers" &&
1303
+ ts.symbolName(symbol) !== "Request" &&
1304
+ ts.symbolName(symbol) !== "Response") ||
1305
+ !symbol.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1306
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
1307
+ return false;
1308
+ }
1309
+ handle = true;
1310
+ }
1311
+ return handle;
1312
+ }
1040
1313
  export function mapType(type, ctx) {
1041
1314
  if (mapTypeDepth >= MAP_TYPE_MAX_DEPTH)
1042
1315
  return null;
@@ -1064,7 +1337,18 @@ export function mapType(type, ctx) {
1064
1337
  const sensitivityAtEntry = contextResolutions;
1065
1338
  mapTypeDepth++;
1066
1339
  try {
1067
- const mapped = mapTypeInner(type, ctx);
1340
+ let mapped;
1341
+ try {
1342
+ mapped = mapTypeInner(type, ctx);
1343
+ }
1344
+ catch (e) {
1345
+ // typescript-go's API can panic serializing a union's members (an
1346
+ // empty tuple cloned as an array literal, `s.match(re) || []`): a
1347
+ // union the checker cannot describe has no representation.
1348
+ if (!topLevel || !ts.isUnreadableConstituentsPanic(e))
1349
+ throw e;
1350
+ mapped = null;
1351
+ }
1068
1352
  if (mapped !== null &&
1069
1353
  memoKey !== null &&
1070
1354
  topLevel &&
@@ -1087,38 +1371,135 @@ function classExprNeedsContext(decl) {
1087
1371
  }
1088
1372
  return false;
1089
1373
  }
1374
+ /** True for the type of a TypeScript object literal with no contextual
1375
+ * type (`const options = { ...location, path }`) that spreads a value
1376
+ * mapping to the checked dynamic (a stdlib options type such as
1377
+ * http.RequestOptions). A literal with a contextual type is built in that
1378
+ * type's representation instead, and JavaScript literals keep their own
1379
+ * rules. */
1380
+ function spreadsCheckedDynamic(symbol, ctx) {
1381
+ if (symbol === undefined || (symbol.flags & ts.SymbolFlags.ObjectLiteral) === 0)
1382
+ return false;
1383
+ const decl = symbol.declarations[0];
1384
+ if (decl === undefined || !ts.isObjectLiteralExpression(decl))
1385
+ return false;
1386
+ if (isJsSourceFile(ts.getSourceFileOfNode(decl)))
1387
+ return false;
1388
+ if (ctx.checker.getContextualType(decl))
1389
+ return false;
1390
+ return decl.properties.nodes.some((prop) => ts.isSpreadAssignment(prop) &&
1391
+ mapType(ctx.checker.getTypeAtLocation(prop.expression), ctx)?.kind === "dyn");
1392
+ }
1090
1393
  function mapTypeInner(type, ctx) {
1091
1394
  const { checker, unions, classNamer, resolveTypeParam } = ctx;
1092
1395
  // TypeScript's intrinsic globalThis symbol has no declaration. A stored
1093
1396
  // reference needs native object identity, including var's undefined state.
1094
1397
  const intrinsic = type.getSymbol();
1095
- if (intrinsic?.name === "globalThis" && checker.declarationsOf(intrinsic).length === 0)
1398
+ if (intrinsic !== undefined &&
1399
+ ts.symbolName(intrinsic) === "globalThis" &&
1400
+ intrinsic.declarations.length === 0)
1096
1401
  return DYN;
1402
+ if (ctx.jsDynamicDeclaration !== undefined && intrinsic !== undefined) {
1403
+ const objectLiteral = (intrinsic.flags & ts.SymbolFlags.ObjectLiteral) !== 0;
1404
+ const classInstance = (intrinsic.flags & ts.SymbolFlags.Class) !== 0 && type.isClassOrInterface();
1405
+ if ((objectLiteral || classInstance) &&
1406
+ intrinsic.declarations.some((decl) => ctx.jsDynamicDeclaration(decl)))
1407
+ return DYN;
1408
+ }
1097
1409
  {
1098
1410
  const moduleId = ctx.moduleNamespaceId?.(type) ?? null;
1099
1411
  if (moduleId !== null)
1100
1412
  return { kind: "moduleNs", moduleId };
1101
1413
  }
1414
+ // A TypeScript object literal that spreads a checked-dynamic value
1415
+ // (`{ ...requestOptions, path, timeout }`): its keys are the source's
1416
+ // runtime keys, which no record shape holds, so the literal rides
1417
+ // checked-dynamic storage like its source.
1418
+ if (spreadsCheckedDynamic(intrinsic, ctx))
1419
+ return DYN;
1102
1420
  // worker_threads.receiveMessageOnPort's `{ message: any } | undefined`:
1103
1421
  // the runtime's { message } object, a checked-dynamic value.
1104
1422
  if (isReceiveMessageResult(type, ctx))
1105
1423
  return DYN;
1424
+ if (isFetchBodyUnion(type, ctx) || isFetchHeadersUnion(type, ctx))
1425
+ return DYN;
1426
+ // Omit/Pick/Partial of a stdlib interface that rides checked-dynamic
1427
+ // storage (`Omit<RequestInit, "body" | "headers">`): every member comes
1428
+ // from that interface, so the value is a subset of the same runtime-read
1429
+ // options object and rides the same storage.
1430
+ if (isDynInterfaceSubset(type, ctx))
1431
+ return DYN;
1432
+ // The lookup-function option union (`LookupOneOptions | LookupAllOptions
1433
+ // | number | undefined`): with a LookupAllOptions arm it is an option bag
1434
+ // dns.lookup reads at run time, so it rides checked-dynamic storage.
1435
+ if (isLookupOptionsUnion(type, ctx))
1436
+ return DYN;
1106
1437
  // @types/node spells child_process.ExecFileException as an intersection
1107
1438
  // type alias over two Error-derived metadata interfaces. The value is
1108
1439
  // still one ordinary Error; recognize the owned alias before generic
1109
1440
  // intersection mapping decomposes it into unsupported utility types.
1110
1441
  const directAlias = type.getAliasSymbol();
1111
- if (directAlias?.name === "ExecFileException" &&
1112
- checker.declarationsOf(directAlias).some((decl) => ctx.isStdlibFile(decl.getSourceFile()))) {
1442
+ if (directAlias !== undefined &&
1443
+ ts.symbolName(directAlias) === "ExecFileException" &&
1444
+ directAlias.declarations.some((decl) => ctx.isStdlibFile(ts.getSourceFileOfNode(decl)))) {
1445
+ return { kind: "object", className: "%Error" };
1446
+ }
1447
+ // child_process.ExecException, exec's callback error, is an interface
1448
+ // extending Error with optional metadata members; the value is one
1449
+ // ordinary Error as well.
1450
+ const execException = type.getSymbol();
1451
+ if (execException !== undefined &&
1452
+ ts.symbolName(execException) === "ExecException" &&
1453
+ execException.declarations.some((decl) => ts.isInterfaceDeclaration(decl) &&
1454
+ ctx.isStdlibFile(ts.getSourceFileOfNode(decl)) &&
1455
+ isDeclaredInAmbientModule(decl, "child_process"))) {
1113
1456
  return { kind: "object", className: "%Error" };
1114
1457
  }
1115
1458
  if (isOsConstantsType(type, ctx) || isLegacyUrlType(type, ctx))
1116
1459
  return DYN;
1460
+ // The WebAssembly API's values have the checked-dynamic representation, so
1461
+ // declarations that merely mention them compile; each reached use of the
1462
+ // API itself is refused at its site (builtins/webassembly.ts).
1463
+ if (isWebAssemblyType(type, ctx))
1464
+ return DYN;
1465
+ // A union over one of them (quickjs-wasi's `BufferSource | WebAssembly.Module`
1466
+ // option) holds that dynamic value too, so the whole union is dynamic.
1467
+ if (type.isUnionType() && ts.constituentTypes(type).some((t) => isWebAssemblyType(t, ctx)))
1468
+ return DYN;
1469
+ // JavaScript inference merges WebAssembly.instantiate's overloads into
1470
+ // `Promise<WebAssemblyInstantiatedSource> & Promise<Instance>`: a promise
1471
+ // of a WebAssembly value either way.
1472
+ if (type.isIntersectionType() &&
1473
+ ts.constituentTypes(type).every((t) => {
1474
+ if (ts.symbolNameOf(t.getSymbol()) !== "Promise")
1475
+ return false;
1476
+ const arg = ctx.checker.getTypeArguments(t)[0];
1477
+ return arg !== undefined && isWebAssemblyType(arg, ctx);
1478
+ }))
1479
+ return { kind: "promise", inner: DYN };
1117
1480
  // Immutable<T> (@scriptc/types) is a deep-readonly view: the value is
1118
1481
  // still the T it maps.
1119
1482
  const immutableSource = immutableSourceType(type, ctx);
1120
1483
  if (immutableSource !== null)
1121
1484
  return mapType(immutableSource, ctx);
1485
+ // Inside an erased generic signature or body, every type that mentions
1486
+ // an erased type parameter is `unknown` (`T[]`, `Map<string, T>`,
1487
+ // `[A, B]`, `T[K]`, callbacks over `T`): its values cross through the
1488
+ // checked-dynamic boundary, as JavaScript sees them. The erased
1489
+ // signature itself maps its parameters and result this way.
1490
+ if ((ctx.erasingSignature || ctx.isErasing?.()) &&
1491
+ !(type.flags & ts.TypeFlags.TypeParameter) &&
1492
+ !checker.getCallSignatures(type).some((sig) => sig === ctx.erasingSignature) &&
1493
+ !ERASURE_KEPT_CONTAINERS.has(ts.symbolNameOf(type.getSymbol()) ?? "") &&
1494
+ mentionsErasedTypeParam(type, ctx, 0)) {
1495
+ contextResolutions++;
1496
+ return DYN;
1497
+ }
1498
+ // Readonly<C> over a program class (Object.freeze's result type) is the
1499
+ // same instance.
1500
+ const readonlyClass = readonlyClassType(type, ctx);
1501
+ if (readonlyClass !== null)
1502
+ return readonlyClass;
1122
1503
  if (resolveTypeParam && type.flags & ts.TypeFlags.TypeParameter) {
1123
1504
  const bound = resolveTypeParam(type);
1124
1505
  if (bound) {
@@ -1157,6 +1538,27 @@ function mapTypeInner(type, ctx) {
1157
1538
  contextResolutions++;
1158
1539
  return viaIndexed;
1159
1540
  }
1541
+ // `Parameters<F>` / `ReturnType<F>` over a bound function-typed
1542
+ // parameter (variadic higher-order wrappers): the checker keeps both
1543
+ // conditionals symbolic inside the body, and their `infer` positions
1544
+ // match a call signature, which matchInferReference cannot decide.
1545
+ const viaSignature = mapBoundSignatureAlias(type, ctx) ?? mapBoundKeyofNeverConditional(type, ctx);
1546
+ if (viaSignature !== null) {
1547
+ contextResolutions++;
1548
+ return viaSignature;
1549
+ }
1550
+ // A conditional type over a bound parameter (`Infer<S["left"]>`, a
1551
+ // mapped type's member): evaluate it against the bindings.
1552
+ if (type.isConditionalType()) {
1553
+ const evaluated = evalMappedTemplate(type, new Map(), new Map(), ctx);
1554
+ if (evaluated && evaluated !== type) {
1555
+ const viaConditional = mapType(evaluated, ctx);
1556
+ if (viaConditional !== null) {
1557
+ contextResolutions++;
1558
+ return viaConditional;
1559
+ }
1560
+ }
1561
+ }
1160
1562
  }
1161
1563
  const widened = checker.getBaseTypeOfLiteralType(type);
1162
1564
  const flags = widened.flags;
@@ -1171,8 +1573,9 @@ function mapTypeInner(type, ctx) {
1171
1573
  // checked-dynamic object retains that distinction through forwarding
1172
1574
  // constructors. Only the standard library's interface gets this ABI.
1173
1575
  const errorOptionsSymbol = widened.getSymbol();
1174
- if (errorOptionsSymbol?.name === "ErrorOptions" &&
1175
- checker.declarationsOf(errorOptionsSymbol).some((d) => ctx.isStdlibFile(d.getSourceFile()))) {
1576
+ if (errorOptionsSymbol !== undefined &&
1577
+ ts.symbolName(errorOptionsSymbol) === "ErrorOptions" &&
1578
+ errorOptionsSymbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1176
1579
  return DYN;
1177
1580
  }
1178
1581
  // node:util.parseArgs config/results are declaration-heavy conditional
@@ -1186,7 +1589,7 @@ function mapTypeInner(type, ctx) {
1186
1589
  {
1187
1590
  const parseArgsSym = widened.getAliasSymbol() ?? widened.getSymbol();
1188
1591
  const belongs = (declaration) => {
1189
- if (!ctx.isStdlibFile(declaration.getSourceFile()))
1592
+ if (!ctx.isStdlibFile(ts.getSourceFileOfNode(declaration)))
1190
1593
  return false;
1191
1594
  let family = false;
1192
1595
  for (let node = declaration; node; node = node.parent) {
@@ -1200,15 +1603,14 @@ function mapTypeInner(type, ctx) {
1200
1603
  return false;
1201
1604
  };
1202
1605
  if (parseArgsSym &&
1203
- PARSE_ARGS_DYN_TYPES.has(parseArgsSym.name) &&
1204
- checker.declarationsOf(parseArgsSym).some(belongs))
1606
+ PARSE_ARGS_DYN_TYPES.has(ts.symbolName(parseArgsSym)) &&
1607
+ parseArgsSym.declarations.some(belongs))
1205
1608
  return DYN;
1206
1609
  // ReturnType and instantiated conditional types can erase the alias.
1207
1610
  // Require every member to retain the util declaration provenance so
1208
1611
  // unrelated records with similar property names keep their own layout.
1209
1612
  const members = checker.getPropertiesOfType(widened);
1210
- if (members.length > 0 &&
1211
- members.every((member) => checker.declarationsOf(member).some(belongs)))
1613
+ if (members.length > 0 && members.every((member) => member.declarations.some(belongs)))
1212
1614
  return DYN;
1213
1615
  }
1214
1616
  // The lib's BOXED wrapper interfaces used as TYPES (`const n: Number =
@@ -1219,9 +1621,15 @@ function mapTypeInner(type, ctx) {
1219
1621
  {
1220
1622
  const boxSym = widened.getSymbol();
1221
1623
  if (boxSym &&
1222
- (boxSym.name === "Number" || boxSym.name === "String" || boxSym.name === "Boolean") &&
1223
- checker.declarationsOf(boxSym).some((d) => ctx.isStdlibFile(d.getSourceFile()))) {
1224
- return boxSym.name === "Number" ? F64 : boxSym.name === "String" ? STRING : BOOL;
1624
+ (ts.symbolName(boxSym) === "Number" ||
1625
+ ts.symbolName(boxSym) === "String" ||
1626
+ ts.symbolName(boxSym) === "Boolean") &&
1627
+ boxSym.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1628
+ return ts.symbolName(boxSym) === "Number"
1629
+ ? F64
1630
+ : ts.symbolName(boxSym) === "String"
1631
+ ? STRING
1632
+ : BOOL;
1225
1633
  }
1226
1634
  }
1227
1635
  // The lib's PRIMITIVE-CONSTRUCTOR interfaces as TYPES (`typeof String`,
@@ -1238,13 +1646,13 @@ function mapTypeInner(type, ctx) {
1238
1646
  {
1239
1647
  const ctorSym = widened.getSymbol();
1240
1648
  if (ctorSym &&
1241
- (ctorSym.name === "StringConstructor" ||
1242
- ctorSym.name === "NumberConstructor" ||
1243
- ctorSym.name === "BooleanConstructor") &&
1244
- checker.declarationsOf(ctorSym).some((d) => ctx.isStdlibFile(d.getSourceFile()))) {
1245
- return funcOf([STRING], ctorSym.name === "StringConstructor"
1649
+ (ts.symbolName(ctorSym) === "StringConstructor" ||
1650
+ ts.symbolName(ctorSym) === "NumberConstructor" ||
1651
+ ts.symbolName(ctorSym) === "BooleanConstructor") &&
1652
+ ctorSym.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1653
+ return funcOf([STRING], ts.symbolName(ctorSym) === "StringConstructor"
1246
1654
  ? STRING
1247
- : ctorSym.name === "NumberConstructor"
1655
+ : ts.symbolName(ctorSym) === "NumberConstructor"
1248
1656
  ? F64
1249
1657
  : BOOL);
1250
1658
  }
@@ -1348,16 +1756,21 @@ function mapTypeInner(type, ctx) {
1348
1756
  return hasStr ? STRING : F64;
1349
1757
  }
1350
1758
  }
1351
- // @scriptc/experimental's LifetimeRegion and InternTable: synthetic
1352
- // program classes, provenance-checked by the package's declaration file.
1759
+ // @scriptc/experimental's LifetimeRegion, InternTable and ThreadSlots:
1760
+ // synthetic program classes, provenance-checked by the package's
1761
+ // declaration file.
1353
1762
  {
1354
1763
  const classSym = widened.getSymbol();
1355
- const name = classSym?.name;
1356
- if (name === "LifetimeRegion" || name === "InternTable") {
1357
- for (const d of checker.declarationsOf(classSym)) {
1764
+ const name = ts.symbolNameOf(classSym);
1765
+ if (name === "LifetimeRegion" || name === "InternTable" || name === "ThreadSlots") {
1766
+ for (const d of classSym.declarations) {
1358
1767
  if (!ts.isClassDeclaration(d))
1359
1768
  continue;
1360
- const synthetic = name === "LifetimeRegion" ? ctx.lifetimeRegionClass?.(d) : ctx.internTableClass?.(d);
1769
+ const synthetic = name === "LifetimeRegion"
1770
+ ? ctx.lifetimeRegionClass?.(d)
1771
+ : name === "InternTable"
1772
+ ? ctx.internTableClass?.(d)
1773
+ : ctx.threadSlotsClass?.(d);
1361
1774
  if (synthetic)
1362
1775
  return synthetic;
1363
1776
  }
@@ -1366,15 +1779,33 @@ function mapTypeInner(type, ctx) {
1366
1779
  // Declaration-only package types have no compiled implementation.
1367
1780
  // Primitive and container types retain their structural mappings; types
1368
1781
  // owned by the standard library or explicit host mappings are handled
1369
- // by their dedicated native rules.
1370
- const npmSym = widened.getAliasSymbol() ?? widened.getSymbol();
1371
- const npmDecls = npmSym ? checker.declarationsOf(npmSym) : undefined;
1372
- if (npmDecls &&
1373
- npmDecls.length > 0 &&
1374
- npmDecls.every((d) => {
1375
- const sf = d.getSourceFile();
1376
- return sf.isDeclarationFile && !ctx.isStdlibFile(sf) && !ctx.isExternalTypeFile(sf);
1377
- })) {
1782
+ // by their dedicated native rules. Pure type shapes — interfaces, type
1783
+ // aliases, and object or mapped type literals with no value declaration
1784
+ // merged in — describe data, not an implementation: a program value of
1785
+ // such a type is one the program built itself (`import type` from a
1786
+ // types-only package), so it maps structurally like a local declaration.
1787
+ // Values the package itself would produce stay refused at their import.
1788
+ const packageOnly = (sym) => {
1789
+ const decls = sym ? sym.declarations : undefined;
1790
+ return decls &&
1791
+ decls.length > 0 &&
1792
+ decls.every((d) => {
1793
+ const sf = ts.getSourceFileOfNode(d);
1794
+ return sf.isDeclarationFile && !ctx.isStdlibFile(sf) && !ctx.isExternalTypeFile(sf);
1795
+ })
1796
+ ? decls
1797
+ : null;
1798
+ };
1799
+ const pureTypeShape = (decls) => decls === null ||
1800
+ decls.every((d) => packageTypeFile(ts.getSourceFileOfNode(d), ctx) &&
1801
+ (ts.isInterfaceDeclaration(d) ||
1802
+ ts.isTypeAliasDeclaration(d) ||
1803
+ ts.isTypeLiteralNode(d) ||
1804
+ ts.isMappedTypeNode(d)));
1805
+ const aliasDecls = packageOnly(widened.getAliasSymbol());
1806
+ const ownDecls = packageOnly(widened.getSymbol());
1807
+ if ((aliasDecls !== null || (widened.getAliasSymbol() === undefined && ownDecls !== null)) &&
1808
+ !(pureTypeShape(aliasDecls) && pureTypeShape(ownDecls))) {
1378
1809
  return null;
1379
1810
  }
1380
1811
  // Module namespaces were claimed above when they name compiled source
@@ -1567,19 +1998,24 @@ function mapTypeInner(type, ctx) {
1567
1998
  // Class instances name a program class. The same symbol with construct
1568
1999
  // signatures names its static side, mapped to classval below.
1569
2000
  const widenedSym = widened.getSymbol();
1570
- const classDecl = widenedSym ? checker.valueDeclarationOf(widenedSym) : undefined;
2001
+ const classDecl = widenedSym ? widenedSym.valueDeclaration : undefined;
1571
2002
  if (classDecl &&
1572
2003
  (ts.isClassDeclaration(classDecl) || ts.isClassExpression(classDecl)) &&
1573
2004
  // Nameless class DECLARATIONS are legal only as `export default class
1574
2005
  // {}` — classNamer spells them "%anon" (unique per file), the same
1575
2006
  // name their collection registered.
1576
- !classDecl.getSourceFile().isDeclarationFile &&
1577
- checker.getConstructSignatures(widened).length === 0) {
1578
- // Declared OUTSIDE the lowered program (reached through the type world
1579
- // alone — jsdoc `typeof import()` over a never-required module): the
1580
- // class will never register, so the instance type is unmappable, not
1581
- // an object type naming a struct that cannot exist.
1582
- if (!ctx.isProgramFile(classDecl.getSourceFile()))
2007
+ !ts.getSourceFileOfNode(classDecl).isDeclarationFile &&
2008
+ checker.getConstructSignatures(widened).length === 0 &&
2009
+ // A TypeScript class declared OUTSIDE the lowered program (reached
2010
+ // through `import type` alone) never registers, and the program can
2011
+ // hold no instance of it: its instance type maps below as the
2012
+ // structural type it describes, like an interface.
2013
+ (ctx.isProgramFile(ts.getSourceFileOfNode(classDecl)) ||
2014
+ isJsSourceFile(ts.getSourceFileOfNode(classDecl)))) {
2015
+ // A JavaScript class outside the lowered program (jsdoc `typeof
2016
+ // import()` over a never-required module) stays unmappable: JSDoc
2017
+ // types are not checked, so its slots fall back to the dynamic value.
2018
+ if (!ctx.isProgramFile(ts.getSourceFileOfNode(classDecl)))
1583
2019
  return null;
1584
2020
  // The class inside a MIXIN function: per-call-site instantiations
1585
2021
  // share this one node — the CURRENT instantiation (collecting or
@@ -1593,7 +2029,7 @@ function mapTypeInner(type, ctx) {
1593
2029
  }
1594
2030
  }
1595
2031
  if (classExprNeedsContext(classDecl)) {
1596
- const local = ctx.localClassInstance?.(classDecl);
2032
+ const local = ctx.localClassInstance?.(classDecl, widened);
1597
2033
  if (local)
1598
2034
  contextResolutions++;
1599
2035
  return local ?? null;
@@ -1601,7 +2037,7 @@ function mapTypeInner(type, ctx) {
1601
2037
  // A GENERIC class's instance type (`Box<number>`) maps to the concrete
1602
2038
  // INSTANTIATION's class (`Box%0`), registered on demand — the Lowerer
1603
2039
  // hook owns the instance table (monomorphization by flow).
1604
- if (classDecl.typeParameters) {
2040
+ if (classDecl.typeParameters?.nodes) {
1605
2041
  const instance = ctx.genericClassInstance?.(classDecl, widened, (argument) => mapType(argument, ctx)) ??
1606
2042
  null;
1607
2043
  // Before the generic declaration's collection turn, the hook can only
@@ -1613,14 +2049,21 @@ function mapTypeInner(type, ctx) {
1613
2049
  }
1614
2050
  return { kind: "object", className: classNamer(classDecl) };
1615
2051
  }
2052
+ // A runtime-provided class's static side (`typeof EventEmitter`,
2053
+ // `typeof Readable`, `ErrorConstructor`): that class's value.
2054
+ {
2055
+ const runtimeClass = ctx.runtimeClassValue?.(widened);
2056
+ if (runtimeClass)
2057
+ return { kind: "classval", className: runtimeClass };
2058
+ }
1616
2059
  // The class STATIC side (`typeof C` — the class name as a value): the
1617
2060
  // same symbol WITH its construct signatures. Program classes only; lib
1618
2061
  // and package statics keep their fences.
1619
2062
  if (classDecl &&
1620
2063
  (ts.isClassDeclaration(classDecl) || ts.isClassExpression(classDecl)) &&
1621
- !classDecl.getSourceFile().isDeclarationFile &&
2064
+ !ts.getSourceFileOfNode(classDecl).isDeclarationFile &&
1622
2065
  checker.getConstructSignatures(widened).length > 0) {
1623
- if (!ctx.isProgramFile(classDecl.getSourceFile()))
2066
+ if (!ctx.isProgramFile(ts.getSourceFileOfNode(classDecl)))
1624
2067
  return null;
1625
2068
  // The MIXIN class node's static side (`typeof C` inside the mixin):
1626
2069
  // the current instantiation's classval, like the instance type above.
@@ -1632,7 +2075,8 @@ function mapTypeInner(type, ctx) {
1632
2075
  }
1633
2076
  }
1634
2077
  if (classExprNeedsContext(classDecl)) {
1635
- const local = ctx.localClassInstance?.(classDecl);
2078
+ const ctorSigs = checker.getConstructSignatures(widened);
2079
+ const local = ctx.localClassInstance?.(classDecl, ctorSigs.length === 1 ? checker.getReturnTypeOfSignature(ctorSigs[0]) : undefined);
1636
2080
  if (local?.kind === "object") {
1637
2081
  contextResolutions++;
1638
2082
  return { kind: "classval", className: local.className };
@@ -1645,7 +2089,7 @@ function mapTypeInner(type, ctx) {
1645
2089
  // the instantiation's classval. Uninstantiated `typeof Box` keeps the
1646
2090
  // type parameter in the construct signature's return — unmapped (the
1647
2091
  // family has no thunk and no single constructor ABI).
1648
- if (classDecl.typeParameters) {
2092
+ if (classDecl.typeParameters?.nodes) {
1649
2093
  const ctorSigs = checker.getConstructSignatures(widened);
1650
2094
  if (ctorSigs.length !== 1)
1651
2095
  return null;
@@ -1681,10 +2125,9 @@ function mapTypeInner(type, ctx) {
1681
2125
  // outside stays unmapped — callers report the component fence (SC2009)
1682
2126
  // naming the offending half, as does the `new Map` lowering per site.
1683
2127
  const psym = widened.getSymbol();
1684
- const isStdlibInterface = (name) => psym?.name === name &&
1685
- checker
1686
- .declarationsOf(psym)
1687
- .some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()));
2128
+ const isStdlibInterface = (name) => psym !== undefined &&
2129
+ ts.symbolName(psym) === name &&
2130
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
1688
2131
  // The builtin Error classes: references to the lib's Error interfaces map to the runtime-provided class
1689
2132
  // hierarchy (provenance, not the name — a user's own `class Error`
1690
2133
  // resolved through the class-instance branch above, and a user
@@ -1697,10 +2140,9 @@ function mapTypeInner(type, ctx) {
1697
2140
  }
1698
2141
  // node:assert's AssertionError is declared as a class (in the shipped
1699
2142
  // fallback and in @types/node), not as a lib interface.
1700
- if (psym?.name === "AssertionError" &&
1701
- checker
1702
- .declarationsOf(psym)
1703
- .some((d) => ts.isClassDeclaration(d) && ctx.isStdlibFile(d.getSourceFile())))
2143
+ if (psym !== undefined &&
2144
+ ts.symbolName(psym) === "AssertionError" &&
2145
+ psym.declarations.some((d) => ts.isClassDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
1704
2146
  return { kind: "object", className: "%AssertionError" };
1705
2147
  // The lib's `Object` interface is a TOP type: tsc admits every
1706
2148
  // non-nullish value into an `Object` slot (`const x: Object = "s"`), so
@@ -1716,12 +2158,11 @@ function mapTypeInner(type, ctx) {
1716
2158
  // module lowering before generic number operations can observe the
1717
2159
  // representation. The node:module class's merged instance interface is
1718
2160
  // included, while unrelated user interfaces named Module stay structural.
1719
- if ((psym?.name === "ScriptcModule" || psym?.name === "Module") &&
1720
- checker
1721
- .declarationsOf(psym)
1722
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1723
- ctx.isStdlibFile(d.getSourceFile()) &&
1724
- (psym.name === "ScriptcModule" ||
2161
+ if (((psym !== undefined && ts.symbolName(psym) === "ScriptcModule") ||
2162
+ (psym !== undefined && ts.symbolName(psym) === "Module")) &&
2163
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2164
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2165
+ (ts.symbolName(psym) === "ScriptcModule" ||
1725
2166
  isDeclaredInAmbientNamespace(d, "NodeJS") ||
1726
2167
  isDeclaredInAmbientModule(d, "module")))) {
1727
2168
  return F64;
@@ -1733,11 +2174,10 @@ function mapTypeInner(type, ctx) {
1733
2174
  // (generic) class plus a same-named interface — and @types/node's
1734
2175
  // NodeJS.EventEmitter interface (the structural surface net.Socket
1735
2176
  // et al. extend) is the same runtime value. Provenance-checked.
1736
- if (psym?.name === "EventEmitter" &&
1737
- checker
1738
- .declarationsOf(psym)
1739
- .some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
1740
- ctx.isStdlibFile(d.getSourceFile()) &&
2177
+ if (psym !== undefined &&
2178
+ ts.symbolName(psym) === "EventEmitter" &&
2179
+ psym.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
2180
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
1741
2181
  (isDeclaredInAmbientModule(d, "events") || isDeclaredInAmbientNamespace(d, "NodeJS")))) {
1742
2182
  return { kind: "object", className: RUNTIME_EMITTER_CLASS };
1743
2183
  }
@@ -1745,11 +2185,10 @@ function mapTypeInner(type, ctx) {
1745
2185
  // value is an f64 handle into the runtime's registry (the Timeout-id
1746
2186
  // precedent). The NAME is generic, so the provenance check adds the
1747
2187
  // enclosing ambient module, like net.Server.
1748
- if (psym?.name === "Interface" &&
1749
- checker
1750
- .declarationsOf(psym)
1751
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1752
- ctx.isStdlibFile(d.getSourceFile()) &&
2188
+ if (psym !== undefined &&
2189
+ ts.symbolName(psym) === "Interface" &&
2190
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2191
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
1753
2192
  (isDeclaredInAmbientModule(d, "readline") ||
1754
2193
  isDeclaredInAmbientModule(d, "readline/promises")))) {
1755
2194
  return F64;
@@ -1757,21 +2196,19 @@ function mapTypeInner(type, ctx) {
1757
2196
  // readline.Key: emitKeys' key object stays a checked-dynamic value, so
1758
2197
  // it keeps Node's own shape (an undefined name, the escape sequences'
1759
2198
  // code member).
1760
- if (psym?.name === "Key" &&
1761
- checker
1762
- .declarationsOf(psym)
1763
- .some((d) => ts.isInterfaceDeclaration(d) &&
1764
- ctx.isStdlibFile(d.getSourceFile()) &&
2199
+ if (psym !== undefined &&
2200
+ ts.symbolName(psym) === "Key" &&
2201
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2202
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
1765
2203
  (isDeclaredInAmbientModule(d, "readline") ||
1766
2204
  isDeclaredInAmbientModule(d, "readline/promises")))) {
1767
2205
  return DYN;
1768
2206
  }
1769
2207
  // readline/promises.Readline: an f64 handle the same way.
1770
- if (psym?.name === "Readline" &&
1771
- checker
1772
- .declarationsOf(psym)
1773
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1774
- ctx.isStdlibFile(d.getSourceFile()) &&
2208
+ if (psym !== undefined &&
2209
+ ts.symbolName(psym) === "Readline" &&
2210
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2211
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
1775
2212
  isDeclaredInAmbientModule(d, "readline/promises"))) {
1776
2213
  return F64;
1777
2214
  }
@@ -1781,39 +2218,36 @@ function mapTypeInner(type, ctx) {
1781
2218
  // Provenance: the name is specific enough that stdlib-file provenance
1782
2219
  // plus the ambient module suffices for both the fallback declarations
1783
2220
  // and @types/node's class Channel<StoreType, ContextType>.
1784
- if (psym?.name === "Channel" &&
1785
- checker
1786
- .declarationsOf(psym)
1787
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1788
- ctx.isStdlibFile(d.getSourceFile()) &&
2221
+ if (psym !== undefined &&
2222
+ ts.symbolName(psym) === "Channel" &&
2223
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2224
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
1789
2225
  isDeclaredInAmbientModule(d, "diagnostics_channel"))) {
1790
2226
  return F64;
1791
2227
  }
1792
2228
  // async_hooks.AsyncLocalStorage: the store value is an f64 handle into
1793
2229
  // the runtime's store id space (the Channel story — stores are
1794
2230
  // process-lived; contexts ride the fiber machinery).
1795
- if (psym?.name === "AsyncLocalStorage" &&
1796
- checker
1797
- .declarationsOf(psym)
1798
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1799
- ctx.isStdlibFile(d.getSourceFile()) &&
2231
+ if (psym !== undefined &&
2232
+ ts.symbolName(psym) === "AsyncLocalStorage" &&
2233
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2234
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
1800
2235
  isDeclaredInAmbientModule(d, "async_hooks"))) {
1801
2236
  return F64;
1802
2237
  }
1803
2238
  // diagnostics_channel.TracingChannel: the same f64-handle story over the
1804
2239
  // runtime's tracing registry (five event channels per entry).
1805
- if (psym?.name === "TracingChannel" &&
1806
- checker
1807
- .declarationsOf(psym)
1808
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1809
- ctx.isStdlibFile(d.getSourceFile()) &&
2240
+ if (psym !== undefined &&
2241
+ ts.symbolName(psym) === "TracingChannel" &&
2242
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2243
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
1810
2244
  isDeclaredInAmbientModule(d, "diagnostics_channel"))) {
1811
2245
  return F64;
1812
2246
  }
1813
2247
  // Node names this result; the ambient WHATWG declaration uses a type literal.
1814
2248
  const encodeResult = psym &&
1815
- checker.declarationsOf(psym).some((decl) => {
1816
- if (!ctx.isStdlibFile(decl.getSourceFile()))
2249
+ psym.declarations.some((decl) => {
2250
+ if (!ctx.isStdlibFile(ts.getSourceFileOfNode(decl)))
1817
2251
  return false;
1818
2252
  if (ts.isInterfaceDeclaration(decl) && decl.name.text === "EncodeIntoResult")
1819
2253
  return true;
@@ -1837,16 +2271,15 @@ function mapTypeInner(type, ctx) {
1837
2271
  };
1838
2272
  // WHATWG codec instances have ordinary reference identity and ownership.
1839
2273
  // Their private encoding slot is omitted from enumeration and JSON.
1840
- if ((psym?.name === "TextEncoder" || psym?.name === "TextDecoder") &&
1841
- checker
1842
- .declarationsOf(psym)
1843
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1844
- ctx.isStdlibFile(d.getSourceFile()))) {
2274
+ if (((psym !== undefined && ts.symbolName(psym) === "TextEncoder") ||
2275
+ (psym !== undefined && ts.symbolName(psym) === "TextDecoder")) &&
2276
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2277
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1845
2278
  return {
1846
2279
  kind: "record",
1847
2280
  shapeId: ctx.shapes.intern([
1848
- { name: `%${psym.name}`, type: F64 },
1849
- ...(psym.name === "TextDecoder"
2281
+ { name: `%${ts.symbolName(psym)}`, type: F64 },
2282
+ ...(ts.symbolName(psym) === "TextDecoder"
1850
2283
  ? [
1851
2284
  { name: "%fatal", type: BOOL },
1852
2285
  { name: "%ignoreBOM", type: BOOL },
@@ -1863,11 +2296,10 @@ function mapTypeInner(type, ctx) {
1863
2296
  // checked like Stats; construction and the write/end methods are
1864
2297
  // special-cased in lowerNew / lowerStringDecoderMethodCall, so the
1865
2298
  // record shape never surfaces.
1866
- if (psym?.name === "StringDecoder" &&
1867
- checker
1868
- .declarationsOf(psym)
1869
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1870
- ctx.isStdlibFile(d.getSourceFile()))) {
2299
+ if (psym !== undefined &&
2300
+ ts.symbolName(psym) === "StringDecoder" &&
2301
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2302
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1871
2303
  return {
1872
2304
  kind: "record",
1873
2305
  shapeId: ctx.shapes.intern([
@@ -1886,14 +2318,14 @@ function mapTypeInner(type, ctx) {
1886
2318
  // record-holding binding forms compile. User-declared literals with
1887
2319
  // these member names keep the ordinary record path (their declarations
1888
2320
  // are not in declaration files).
1889
- const promiseDeclarations = psym ? checker.declarationsOf(psym) : [];
2321
+ const promiseDeclarations = psym ? psym.declarations : [];
1890
2322
  if (flags & ts.TypeFlags.Object &&
1891
2323
  promiseDeclarations.length > 0 &&
1892
- promiseDeclarations.every((d) => d.getSourceFile().isDeclarationFile)) {
2324
+ promiseDeclarations.every((d) => ts.getSourceFileOfNode(d).isDeclarationFile)) {
1893
2325
  const props = checker.getPropertiesOfType(widened);
1894
2326
  if (props.length === 3 &&
1895
- ["promise", "resolve", "reject"].every((n) => props.some((p) => p.name === n))) {
1896
- const promProp = props.find((p) => p.name === "promise");
2327
+ ["promise", "resolve", "reject"].every((n) => props.some((p) => ts.symbolName(p) === n))) {
2328
+ const promProp = props.find((p) => ts.symbolName(p) === "promise");
1897
2329
  const promT = mapType(checker.getTypeOfSymbol(promProp), ctx);
1898
2330
  if (promT?.kind === "promise") {
1899
2331
  const inner = promT.inner;
@@ -1930,6 +2362,27 @@ function mapTypeInner(type, ctx) {
1930
2362
  // stdio and env values. Keep it checked-dynamic for native normalization.
1931
2363
  if (isStdlibInterface("SpawnOptions"))
1932
2364
  return DYN;
2365
+ // dns.LookupAllOptions (`all: true`, the overload whose callback takes
2366
+ // an address list): a lookup option bag dns.lookup reads at run time.
2367
+ // It rides checked-dynamic storage, so the lookup function type that
2368
+ // takes `LookupOneOptions | LookupAllOptions | number` compiles.
2369
+ if (isStdlibInterface("LookupAllOptions"))
2370
+ return DYN;
2371
+ // http.RequestOptions / https.RequestOptions as a declared type: an
2372
+ // option record whose members include functions, agents and signals.
2373
+ // Values ride checked-dynamic storage, like SpawnOptions.
2374
+ if (psym !== undefined &&
2375
+ ts.symbolName(psym) === "RequestOptions" &&
2376
+ psym.declarations.some((d) => {
2377
+ if (!ts.isInterfaceDeclaration(d) || !ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
2378
+ return false;
2379
+ for (let p = d.parent; p !== undefined; p = p.parent) {
2380
+ if (ts.isModuleDeclaration(p) && ts.isStringLiteral(p.name))
2381
+ return HTTP_REQUEST_OPTION_MODULES.has(p.name.text);
2382
+ }
2383
+ return false;
2384
+ }))
2385
+ return DYN;
1933
2386
  // exactly like npm-declared types. Static fetch has one deliberately
1934
2387
  // narrower native representation: Response is an opaque checked-
1935
2388
  // dynamic capsule consumed only by the Response method lowerings, and
@@ -1942,10 +2395,9 @@ function mapTypeInner(type, ctx) {
1942
2395
  // interfaces; @types/node's undici-types declares Response as a class).
1943
2396
  {
1944
2397
  const alias = widened.getAliasSymbol();
1945
- if (alias?.name === "ReadableStreamReadResult" &&
1946
- checker
1947
- .declarationsOf(alias)
1948
- .some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
2398
+ if (alias !== undefined &&
2399
+ ts.symbolName(alias) === "ReadableStreamReadResult" &&
2400
+ alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1949
2401
  const elemTs = widened.getAliasTypeArguments()?.[0];
1950
2402
  const elem = elemTs && elemTs.flags & ts.TypeFlags.Any ? DYN : elemTs ? mapType(elemTs, ctx) : null;
1951
2403
  if (!elem)
@@ -1954,37 +2406,48 @@ function mapTypeInner(type, ctx) {
1954
2406
  }
1955
2407
  }
1956
2408
  if (psym &&
1957
- (psym.name === "ReadableStreamReadValueResult" ||
1958
- psym.name === "ReadableStreamReadDoneResult") &&
1959
- checker
1960
- .declarationsOf(psym)
1961
- .some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
2409
+ (ts.symbolName(psym) === "ReadableStreamReadValueResult" ||
2410
+ ts.symbolName(psym) === "ReadableStreamReadDoneResult") &&
2411
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1962
2412
  const elemTs = checker.getTypeArguments(widened)[0];
1963
2413
  const elem = elemTs && elemTs.flags & ts.TypeFlags.Any ? DYN : elemTs ? mapType(elemTs, ctx) : null;
1964
2414
  if (!elem)
1965
2415
  return null;
1966
2416
  return genResultRecord(elem, VOID, ctx.shapes, ctx.unions);
1967
2417
  }
2418
+ // node:net's SocketAddress and BlockList: native handles (scr_net.c)
2419
+ // whose getters and methods dispatch through the handle.
2420
+ if (((psym !== undefined && ts.symbolName(psym) === "SocketAddress") ||
2421
+ (psym !== undefined && ts.symbolName(psym) === "BlockList")) &&
2422
+ psym.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
2423
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2424
+ return DYN;
2425
+ }
2426
+ // WebCrypto: the crypto global and its subtle object are dynamic
2427
+ // objects, CryptoKey values are native handles (scr_webcrypto.c), and
2428
+ // the algorithm dictionaries the methods take and keys report are plain
2429
+ // checked-dynamic objects.
2430
+ if (psym &&
2431
+ WEBCRYPTO_DYN_TYPES.has(ts.symbolName(psym)) &&
2432
+ psym.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
2433
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2434
+ return DYN;
2435
+ }
1968
2436
  // node:crypto's KeyObject: secret keys are native handles (scr_lib.c)
1969
2437
  // whose getters and methods dispatch through the handle. The JsonWebKey
1970
2438
  // that export() returns is a plain checked-dynamic object.
1971
- if ((psym?.name === "KeyObject" || psym?.name === "JsonWebKey") &&
1972
- checker
1973
- .declarationsOf(psym)
1974
- .some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
1975
- ctx.isStdlibFile(d.getSourceFile()))) {
2439
+ if (((psym !== undefined && ts.symbolName(psym) === "KeyObject") ||
2440
+ (psym !== undefined && ts.symbolName(psym) === "JsonWebKey")) &&
2441
+ psym.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
2442
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1976
2443
  return DYN;
1977
2444
  }
1978
2445
  if (psym &&
1979
- FETCH_AMBIENT_TYPES.includes(psym.name) &&
1980
- !(psym.name === "ReadableStream" &&
1981
- checker
1982
- .declarationsOf(psym)
1983
- .some((d) => ts.isInterfaceDeclaration(d) && isDeclaredInAmbientNamespace(d, "NodeJS"))) &&
1984
- checker
1985
- .declarationsOf(psym)
1986
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1987
- ctx.isStdlibFile(d.getSourceFile()))) {
2446
+ FETCH_AMBIENT_TYPES.includes(ts.symbolName(psym)) &&
2447
+ !(ts.symbolName(psym) === "ReadableStream" &&
2448
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && isDeclaredInAmbientNamespace(d, "NodeJS"))) &&
2449
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2450
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
1988
2451
  return DYN;
1989
2452
  }
1990
2453
  // The stdlib Console interface (the global console and node:console
@@ -1992,19 +2455,21 @@ function mapTypeInner(type, ctx) {
1992
2455
  // representation and consumed by the console method lowerings. The
1993
2456
  // stdlib Disposable (events.addAbortListener's result) and
1994
2457
  // AsyncDisposable are checked objects carrying their Symbol.dispose or
1995
- // Symbol.asyncDispose method.
1996
- if ((psym?.name === "Console" || psym?.name === "Disposable" || psym?.name === "AsyncDisposable") &&
1997
- checker
1998
- .declarationsOf(psym)
1999
- .some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
2458
+ // Symbol.asyncDispose method. A DisposableStack is a native handle whose
2459
+ // methods are function values of its checked-dynamic view.
2460
+ if (((psym !== undefined && ts.symbolName(psym) === "Console") ||
2461
+ (psym !== undefined && ts.symbolName(psym) === "Disposable") ||
2462
+ (psym !== undefined && ts.symbolName(psym) === "AsyncDisposable") ||
2463
+ (psym !== undefined && ts.symbolName(psym) === "DisposableStack")) &&
2464
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2000
2465
  return DYN;
2001
2466
  }
2002
2467
  // node:crypto Cipheriv/Decipheriv values (and @types/node's per-mode
2003
2468
  // interfaces over them) are native handles carried by the checked-dynamic
2004
2469
  // representation; lowerCipherMethodCall dispatches their methods.
2005
2470
  if (psym !== undefined &&
2006
- CIPHER_TYPE_NAMES.has(psym.name) &&
2007
- checker.declarationsOf(psym).some((d) => ctx.isStdlibFile(d.getSourceFile()))) {
2471
+ CIPHER_TYPE_NAMES.has(ts.symbolName(psym)) &&
2472
+ psym.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2008
2473
  return DYN;
2009
2474
  }
2010
2475
  // ReadonlyMap/ReadonlySet are the SAME runtime values as Map/Set — the
@@ -2124,6 +2589,8 @@ function mapTypeInner(type, ctx) {
2124
2589
  // SharedArrayBuffer, and the i32 semantics hold for every other use.
2125
2590
  if (isStdlibInterface("Int32Array"))
2126
2591
  return bytesOf("i32");
2592
+ if (isStdlibInterface("Float16Array"))
2593
+ return bytesOf("f16");
2127
2594
  if (isStdlibInterface("Float32Array"))
2128
2595
  return bytesOf("f32");
2129
2596
  if (isStdlibInterface("Float64Array"))
@@ -2139,11 +2606,10 @@ function mapTypeInner(type, ctx) {
2139
2606
  // (the u8 bytes kind). Declared `interface Buffer` by the shipped
2140
2607
  // fallback and by @types/node (whose NonSharedBuffer alias resolves to
2141
2608
  // the same symbol); provenance-checked like URL.
2142
- if (psym?.name === "Buffer" &&
2143
- checker
2144
- .declarationsOf(psym)
2145
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2146
- ctx.isStdlibFile(d.getSourceFile()))) {
2609
+ if (psym !== undefined &&
2610
+ ts.symbolName(psym) === "Buffer" &&
2611
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2612
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2147
2613
  return bytesOf("u8");
2148
2614
  }
2149
2615
  // URL: the WHATWG URL instance type — declared as a global `interface
@@ -2151,41 +2617,36 @@ function mapTypeInner(type, ctx) {
2151
2617
  // URL` in @types/node's "url" module (`new URL(x)` types as the class's
2152
2618
  // instance type). Provenance, not the name: a user's own URL maps as a
2153
2619
  // record/class like any other.
2154
- if (psym?.name === "URL" &&
2155
- checker
2156
- .declarationsOf(psym)
2157
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2158
- ctx.isStdlibFile(d.getSourceFile()))) {
2620
+ if (psym !== undefined &&
2621
+ ts.symbolName(psym) === "URL" &&
2622
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2623
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2159
2624
  return { kind: "url" };
2160
2625
  }
2161
2626
  // URLSearchParams: the WHATWG live query view — declared as a global
2162
2627
  // interface by the shipped fallback and by @types/node (plus `class
2163
2628
  // URLSearchParams` in the "url" module). Provenance-checked like URL.
2164
- if (psym?.name === "URLSearchParams" &&
2165
- checker
2166
- .declarationsOf(psym)
2167
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2168
- ctx.isStdlibFile(d.getSourceFile()))) {
2629
+ if (psym !== undefined &&
2630
+ ts.symbolName(psym) === "URLSearchParams" &&
2631
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2632
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2169
2633
  return { kind: "searchParams" };
2170
2634
  }
2171
2635
  // fs.Stats: @types/node's `class Stats` (module "fs") or the fallback
2172
2636
  // declarations' interface. Provenance-checked like URL.
2173
- if (psym?.name === "Stats" &&
2174
- checker
2175
- .declarationsOf(psym)
2176
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2177
- ctx.isStdlibFile(d.getSourceFile()))) {
2637
+ if (psym !== undefined &&
2638
+ ts.symbolName(psym) === "Stats" &&
2639
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2640
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2178
2641
  return { kind: "stats" };
2179
2642
  }
2180
2643
  // Capacity snapshots and options keep their live object representation
2181
2644
  // across numeric/BigInt overloads, runtime options, and callbacks.
2182
- if ((psym?.name === "StatsFs" ||
2183
- psym?.name === "BigIntStatsFs" ||
2184
- psym?.name === "StatFsOptions") &&
2185
- checker
2186
- .declarationsOf(psym)
2187
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2188
- ctx.isStdlibFile(d.getSourceFile()) &&
2645
+ if (((psym !== undefined && ts.symbolName(psym) === "StatsFs") ||
2646
+ (psym !== undefined && ts.symbolName(psym) === "BigIntStatsFs") ||
2647
+ (psym !== undefined && ts.symbolName(psym) === "StatFsOptions")) &&
2648
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2649
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2189
2650
  isDeclaredInAmbientModule(d, "fs")))
2190
2651
  return DYN;
2191
2652
  if (isWorkerHandleSymbol(psym, ctx))
@@ -2193,21 +2654,19 @@ function mapTypeInner(type, ctx) {
2193
2654
  // fs/promises.FileHandle: an owned descriptor object. Module provenance
2194
2655
  // distinguishes it from user interfaces with the same name; both the
2195
2656
  // fallback and @types/node declare it in "fs/promises".
2196
- if (psym?.name === "FileHandle" &&
2197
- checker
2198
- .declarationsOf(psym)
2199
- .some((d) => ts.isInterfaceDeclaration(d) &&
2200
- ctx.isStdlibFile(d.getSourceFile()) &&
2657
+ if (psym !== undefined &&
2658
+ ts.symbolName(psym) === "FileHandle" &&
2659
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2660
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2201
2661
  isDeclaredInAmbientModule(d, "fs/promises"))) {
2202
2662
  return { kind: "fileHandle" };
2203
2663
  }
2204
2664
  // fs.Dir: an open directory stream, declared in "fs" by both the
2205
2665
  // fallback and @types/node.
2206
- if (psym?.name === "Dir" &&
2207
- checker
2208
- .declarationsOf(psym)
2209
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2210
- ctx.isStdlibFile(d.getSourceFile()) &&
2666
+ if (psym !== undefined &&
2667
+ ts.symbolName(psym) === "Dir" &&
2668
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2669
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2211
2670
  isDeclaredInAmbientModule(d, "fs"))) {
2212
2671
  return { kind: "dir" };
2213
2672
  }
@@ -2215,24 +2674,21 @@ function mapTypeInner(type, ctx) {
2215
2674
  // Buffer/string split is re-checked at the stdout/stderr READ — status
2216
2675
  // reads work either way) or the fallback declarations' plain interface.
2217
2676
  // Provenance-checked like Stats.
2218
- if (psym?.name === "SpawnSyncReturns" &&
2219
- checker
2220
- .declarationsOf(psym)
2221
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2222
- ctx.isStdlibFile(d.getSourceFile()))) {
2677
+ if (psym !== undefined &&
2678
+ ts.symbolName(psym) === "SpawnSyncReturns" &&
2679
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2680
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2223
2681
  return { kind: "spawnRes" };
2224
2682
  }
2225
2683
  // child_process.ChildProcess and @types/node's stdio-refined return
2226
2684
  // interfaces: all carry the same runtime child handle; the generic
2227
2685
  // refinements only tell the checker which stdio properties are null.
2228
2686
  if (psym !== undefined &&
2229
- (psym.name === "ChildProcess" ||
2230
- psym.name === "ChildProcessWithoutNullStreams" ||
2231
- psym.name === "ChildProcessByStdio") &&
2232
- checker
2233
- .declarationsOf(psym)
2234
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2235
- ctx.isStdlibFile(d.getSourceFile()) &&
2687
+ (ts.symbolName(psym) === "ChildProcess" ||
2688
+ ts.symbolName(psym) === "ChildProcessWithoutNullStreams" ||
2689
+ ts.symbolName(psym) === "ChildProcessByStdio") &&
2690
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2691
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2236
2692
  isDeclaredInAmbientModule(d, "child_process"))) {
2237
2693
  return { kind: "child" };
2238
2694
  }
@@ -2243,64 +2699,62 @@ function mapTypeInner(type, ctx) {
2243
2699
  // declare these inside `declare module "net"` — a declaration outside
2244
2700
  // that module (http's Server) stays unmapped and fences at its use
2245
2701
  // site.
2246
- if ((psym?.name === "Server" || psym?.name === "Socket" || psym?.name === "TLSSocket") &&
2247
- checker.declarationsOf(psym).some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2248
- ctx.isStdlibFile(d.getSourceFile()) &&
2702
+ if (((psym !== undefined && ts.symbolName(psym) === "Server") ||
2703
+ (psym !== undefined && ts.symbolName(psym) === "Socket") ||
2704
+ (psym !== undefined && ts.symbolName(psym) === "TLSSocket")) &&
2705
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2706
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2249
2707
  (isDeclaredInAmbientModule(d, "net") ||
2250
2708
  // http.Server extends net.Server in @types/node — and tls.Server
2251
2709
  // / https.Server extend it transitively: same lowered surface
2252
2710
  // (listen/close/address/'error'), same handle kind. tls.TLSSocket
2253
2711
  // extends net.Socket the same way: post-handshake it IS a net
2254
2712
  // socket to every lowered member.
2255
- (psym.name === "Server" &&
2713
+ (ts.symbolName(psym) === "Server" &&
2256
2714
  (isDeclaredInAmbientModule(d, "http") ||
2257
2715
  isDeclaredInAmbientModule(d, "tls") ||
2258
2716
  isDeclaredInAmbientModule(d, "https"))) ||
2259
- (psym.name === "TLSSocket" && isDeclaredInAmbientModule(d, "tls"))))) {
2260
- return psym.name === "Server" ? { kind: "netServer" } : { kind: "netSocket" };
2717
+ (ts.symbolName(psym) === "TLSSocket" && isDeclaredInAmbientModule(d, "tls"))))) {
2718
+ return ts.symbolName(psym) === "Server" ? { kind: "netServer" } : { kind: "netSocket" };
2261
2719
  }
2262
2720
  // tls.SecureContext: the opaque parsed-cert/key handle SNI callbacks
2263
2721
  // answer with (tls.createSecureContext({ cert, key }) mints it; the TLS
2264
2722
  // server's handshake consumes it). Module-checked like net.Server —
2265
2723
  // @types/node declares `interface SecureContext` inside `declare module
2266
2724
  // "tls"`, and the shipped fallback mirrors it.
2267
- if (psym?.name === "SecureContext" &&
2268
- checker
2269
- .declarationsOf(psym)
2270
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2271
- ctx.isStdlibFile(d.getSourceFile()) &&
2725
+ if (psym !== undefined &&
2726
+ ts.symbolName(psym) === "SecureContext" &&
2727
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2728
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2272
2729
  isDeclaredInAmbientModule(d, "tls"))) {
2273
2730
  return { kind: "secureCtx" };
2274
2731
  }
2275
2732
  // Scrypt's runtime options retain property accessors and aliases. Use
2276
2733
  // checked values so presence probes and repeated getter reads match Node.
2277
- if (psym?.name === "ScryptOptions" &&
2278
- checker
2279
- .declarationsOf(psym)
2280
- .some((d) => ts.isInterfaceDeclaration(d) &&
2281
- ctx.isStdlibFile(d.getSourceFile()) &&
2734
+ if (psym !== undefined &&
2735
+ ts.symbolName(psym) === "ScryptOptions" &&
2736
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2737
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2282
2738
  isDeclaredInAmbientModule(d, "crypto")))
2283
2739
  return DYN;
2284
2740
  // crypto.Hash / crypto.Hmac: native incremental digest handles. Keep
2285
2741
  // provenance module-qualified so user classes with these common names
2286
2742
  // retain their ordinary structural/class representation.
2287
- if ((psym?.name === "Hash" || psym?.name === "Hmac") &&
2288
- checker
2289
- .declarationsOf(psym)
2290
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2291
- ctx.isStdlibFile(d.getSourceFile()) &&
2743
+ if (((psym !== undefined && ts.symbolName(psym) === "Hash") ||
2744
+ (psym !== undefined && ts.symbolName(psym) === "Hmac")) &&
2745
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2746
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2292
2747
  isDeclaredInAmbientModule(d, "crypto"))) {
2293
- return psym.name === "Hash" ? CRYPTOHASH_T : CRYPTOHMAC_T;
2748
+ return ts.symbolName(psym) === "Hash" ? CRYPTOHASH_T : CRYPTOHMAC_T;
2294
2749
  }
2295
2750
  // fs.FSWatcher: the fs.watch handle (scr_watch.c). Module-checked like
2296
2751
  // net.Server — @types/node declares `interface FSWatcher extends
2297
2752
  // EventEmitter` inside `declare module "fs"`, and the shipped fallback
2298
2753
  // mirrors it.
2299
- if (psym?.name === "FSWatcher" &&
2300
- checker
2301
- .declarationsOf(psym)
2302
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2303
- ctx.isStdlibFile(d.getSourceFile()) &&
2754
+ if (psym !== undefined &&
2755
+ ts.symbolName(psym) === "FSWatcher" &&
2756
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2757
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2304
2758
  isDeclaredInAmbientModule(d, "fs"))) {
2305
2759
  return { kind: "fsWatcher" };
2306
2760
  }
@@ -2321,41 +2775,70 @@ function mapTypeInner(type, ctx) {
2321
2775
  // global-namespace interface real code writes in its own signatures —
2322
2776
  // prefixStream's `output` param). The representation is the raw fd
2323
2777
  // scalar; the lowered surface is write(string).
2324
- if ((psym?.name === "WriteStream" &&
2325
- checker
2326
- .declarationsOf(psym)
2327
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2328
- ctx.isStdlibFile(d.getSourceFile()) &&
2778
+ // Under the program's general stream representation (generalNodeStreams)
2779
+ // NodeJS.WritableStream is the runtime Writable instead: the process
2780
+ // streams convert into it where they flow (process.stdioWritable).
2781
+ // Checked-dynamic stream slots: an intersection over a NodeJS stream
2782
+ // interface (`NodeJS.ReadableStream & { destroy?(): void }`) holds the
2783
+ // same values as the interface.
2784
+ if (ctx.dynNodeStreams === true &&
2785
+ (type.flags & ts.TypeFlags.Intersection) !== 0 &&
2786
+ ts.constituentTypes(type).some((part) => {
2787
+ const sym = part.getSymbol();
2788
+ return (((sym !== undefined && ts.symbolName(sym) === "ReadableStream") ||
2789
+ (sym !== undefined && ts.symbolName(sym) === "WritableStream")) &&
2790
+ sym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2791
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2792
+ isDeclaredInAmbientNamespace(d, "NodeJS")));
2793
+ })) {
2794
+ return DYN;
2795
+ }
2796
+ const nodeWritableInterface = psym !== undefined &&
2797
+ ts.symbolName(psym) === "WritableStream" &&
2798
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2799
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2800
+ isDeclaredInAmbientNamespace(d, "NodeJS"));
2801
+ if (nodeWritableInterface && ctx.generalNodeStreams === true) {
2802
+ return ctx.dynNodeStreams === true ? DYN : { kind: "object", className: "%Writable" };
2803
+ }
2804
+ if ((psym !== undefined &&
2805
+ ts.symbolName(psym) === "WriteStream" &&
2806
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2807
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2329
2808
  (isDeclaredInAmbientModule(d, "tty") ||
2330
- (isDeclaredInAmbientModule(d, "process") &&
2331
- isDeclaredInAmbientNamespace(d, "NodeJS"))))) ||
2332
- (psym?.name === "WritableStream" &&
2333
- checker
2334
- .declarationsOf(psym)
2335
- .some((d) => ts.isInterfaceDeclaration(d) &&
2336
- ctx.isStdlibFile(d.getSourceFile()) &&
2337
- isDeclaredInAmbientNamespace(d, "NodeJS")))) {
2809
+ (isDeclaredInAmbientModule(d, "process") && isDeclaredInAmbientNamespace(d, "NodeJS"))))) ||
2810
+ nodeWritableInterface) {
2338
2811
  return PROCSTREAM_T;
2339
2812
  }
2340
2813
  // A piped child stdin writer. The fallback declarations give it the
2341
2814
  // dedicated ChildStdin name; @types/node spells the same value as
2342
2815
  // stream.Writable. As with stream.Readable below, unsupported producers
2343
2816
  // of the broad @types class fence where they are constructed.
2344
- if ((psym?.name === "ChildStdin" &&
2345
- checker
2346
- .declarationsOf(psym)
2347
- .some((d) => ts.isInterfaceDeclaration(d) &&
2348
- ctx.isStdlibFile(d.getSourceFile()) &&
2817
+ if ((psym !== undefined &&
2818
+ ts.symbolName(psym) === "ChildStdin" &&
2819
+ ctx.generalNodeStreams !== true &&
2820
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2821
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2349
2822
  isDeclaredInAmbientModule(d, "child_process"))) ||
2350
- (psym?.name === "Writable" &&
2351
- checker
2352
- .declarationsOf(psym)
2353
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2354
- ctx.isStdlibFile(d.getSourceFile()) &&
2355
- isNodeTypesPath(d.getSourceFile().fileName) &&
2823
+ (psym !== undefined &&
2824
+ ts.symbolName(psym) === "Writable" &&
2825
+ ctx.generalNodeStreams !== true &&
2826
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2827
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2828
+ isNodeTypesPath(ts.getSourceFileOfNode(d).fileName) &&
2356
2829
  isDeclaredInAmbientModule(d, "stream")))) {
2357
2830
  return { kind: "childWriter" };
2358
2831
  }
2832
+ // Under the general stream representation the fallback declarations'
2833
+ // ChildStdin is the runtime Writable too (child.stdioStream bridges it).
2834
+ if (ctx.generalNodeStreams === true &&
2835
+ psym !== undefined &&
2836
+ ts.symbolName(psym) === "ChildStdin" &&
2837
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2838
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2839
+ isDeclaredInAmbientModule(d, "child_process"))) {
2840
+ return { kind: "object", className: "%Writable" };
2841
+ }
2359
2842
  // The static node:stream classes (the shipped fallback declarations —
2360
2843
  // NOT @types/node, whose stream.Readable also types child stdio; under
2361
2844
  // @types/node the childStream mapping below keeps priority and the
@@ -2363,93 +2846,102 @@ function mapTypeInner(type, ctx) {
2363
2846
  // branch: the fallback's Readable must map to the runtime class, and
2364
2847
  // under the fallback child.stdout is NodeJS.ReadableStream (its own
2365
2848
  // branch below), so the two never collide.
2849
+ // @types/node's Duplex/Transform/PassThrough classes have no child-stdio
2850
+ // reading, so they map to the runtime classes too; its Readable and
2851
+ // Writable join them under the general representation.
2366
2852
  for (const [irName, rec] of RUNTIME_STREAM_CLASSES) {
2367
- if (psym?.name === rec.lib &&
2368
- checker
2369
- .declarationsOf(psym)
2370
- .some((d) => ts.isClassDeclaration(d) &&
2371
- ctx.isStdlibFile(d.getSourceFile()) &&
2372
- !isNodeTypesPath(d.getSourceFile().fileName) &&
2853
+ if (psym !== undefined &&
2854
+ ts.symbolName(psym) === rec.lib &&
2855
+ psym.declarations.some((d) => ts.isClassDeclaration(d) &&
2856
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2857
+ (!isNodeTypesPath(ts.getSourceFileOfNode(d).fileName) ||
2858
+ ctx.generalNodeStreams === true ||
2859
+ (rec.lib !== "Readable" && rec.lib !== "Writable")) &&
2373
2860
  isDeclaredInAmbientModule(d, "stream"))) {
2374
2861
  return { kind: "object", className: irName };
2375
2862
  }
2376
2863
  }
2377
- // node:zlib's stream classes (the shipped fallback declarations): their
2378
- // instances are runtime Transform streams.
2864
+ // node:zlib's stream classes (the shipped fallback declarations and
2865
+ // @types/node's): their instances are runtime Transform streams.
2379
2866
  if (psym !== undefined &&
2380
- ZLIB_STREAM_MODES.has(psym.name) &&
2381
- checker
2382
- .declarationsOf(psym)
2383
- .some((d) => ts.isClassDeclaration(d) &&
2384
- ctx.isStdlibFile(d.getSourceFile()) &&
2385
- !isNodeTypesPath(d.getSourceFile().fileName) &&
2867
+ ZLIB_STREAM_MODES.has(ts.symbolName(psym)) &&
2868
+ psym.declarations.some((d) => (ts.isClassDeclaration(d) ||
2869
+ (ts.isInterfaceDeclaration(d) && isNodeTypesPath(ts.getSourceFileOfNode(d).fileName))) &&
2870
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2386
2871
  isDeclaredInAmbientModule(d, "zlib"))) {
2387
2872
  return { kind: "object", className: "%Transform" };
2388
2873
  }
2389
- // fs.ReadStream / fs.WriteStream (the shipped fallback declarations):
2390
- // their instances are runtime Readable / Writable streams
2391
- // (scr_fs_stream.c).
2392
- if ((psym?.name === "ReadStream" || psym?.name === "WriteStream") &&
2393
- checker
2394
- .declarationsOf(psym)
2395
- .some((d) => ts.isClassDeclaration(d) &&
2396
- ctx.isStdlibFile(d.getSourceFile()) &&
2397
- !isNodeTypesPath(d.getSourceFile().fileName) &&
2874
+ // fs.ReadStream / fs.WriteStream (the shipped fallback declarations and
2875
+ // @types/node's): their instances are runtime Readable / Writable
2876
+ // streams (scr_fs_stream.c).
2877
+ if (((psym !== undefined && ts.symbolName(psym) === "ReadStream") ||
2878
+ (psym !== undefined && ts.symbolName(psym) === "WriteStream")) &&
2879
+ psym.declarations.some((d) => ts.isClassDeclaration(d) &&
2880
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2398
2881
  isDeclaredInAmbientModule(d, "fs"))) {
2399
- return { kind: "object", className: psym.name === "ReadStream" ? "%Readable" : "%Writable" };
2882
+ return {
2883
+ kind: "object",
2884
+ className: ts.symbolName(psym) === "ReadStream" ? "%Readable" : "%Writable",
2885
+ };
2400
2886
  }
2401
- if ((psym?.name === "Readable" &&
2402
- checker
2403
- .declarationsOf(psym)
2404
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2405
- ctx.isStdlibFile(d.getSourceFile()) &&
2887
+ if ((psym !== undefined &&
2888
+ ts.symbolName(psym) === "Readable" &&
2889
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2890
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2406
2891
  isDeclaredInAmbientModule(d, "stream"))) ||
2407
- (psym?.name === "ReadableStream" &&
2408
- checker
2409
- .declarationsOf(psym)
2410
- .some((d) => ts.isInterfaceDeclaration(d) &&
2411
- ctx.isStdlibFile(d.getSourceFile()) &&
2892
+ (psym !== undefined &&
2893
+ ts.symbolName(psym) === "ReadableStream" &&
2894
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2895
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2412
2896
  isDeclaredInAmbientNamespace(d, "NodeJS")))) {
2897
+ // The general representation: the runtime Readable, which child
2898
+ // stdio reads produce through the child stream bridge. With
2899
+ // checked-dynamic stream slots, NodeJS.ReadableStream holds any
2900
+ // stream value (dyn-streams.ts); stream.Readable keeps the class.
2901
+ if (ctx.generalNodeStreams === true) {
2902
+ if (ctx.dynNodeStreams === true && ts.symbolName(psym) === "ReadableStream")
2903
+ return DYN;
2904
+ return { kind: "object", className: "%Readable" };
2905
+ }
2413
2906
  return { kind: "childStream" };
2414
2907
  }
2415
2908
  // dgram.Socket: the same ambiguous "Socket" name disambiguated by its
2416
2909
  // enclosing ambient module — @types/node's `class Socket extends
2417
2910
  // EventEmitter` and the fallback declarations' interface both live
2418
2911
  // inside `declare module "dgram"`.
2419
- if (psym?.name === "Socket" &&
2420
- checker
2421
- .declarationsOf(psym)
2422
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2423
- ctx.isStdlibFile(d.getSourceFile()) &&
2912
+ if (psym !== undefined &&
2913
+ ts.symbolName(psym) === "Socket" &&
2914
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2915
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2424
2916
  isDeclaredInAmbientModule(d, "dgram"))) {
2425
2917
  return { kind: "dgramSocket" };
2426
2918
  }
2427
2919
  // node:test's TestContext — the test-body parameter (`test('x', (t) =>
2428
- // ...)`). @types/node's `class TestContext` and the fallback
2429
- // declarations' interface both live inside `declare module "node:test"`
2430
- // (isDeclaredInAmbientModule answers for both spellings).
2431
- if (psym?.name === "TestContext" &&
2432
- checker
2433
- .declarationsOf(psym)
2434
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2435
- ctx.isStdlibFile(d.getSourceFile()) &&
2920
+ // ...)`) — and SuiteContext, the describe-body and suite-hook parameter:
2921
+ // both are the runner's node for the test or suite. @types/node's
2922
+ // classes and the fallback declarations' interfaces all live inside
2923
+ // `declare module "node:test"` (isDeclaredInAmbientModule answers for
2924
+ // both spellings).
2925
+ if (((psym !== undefined && ts.symbolName(psym) === "TestContext") ||
2926
+ (psym !== undefined && ts.symbolName(psym) === "SuiteContext")) &&
2927
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2928
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2436
2929
  isDeclaredInAmbientModule(d, "test"))) {
2437
2930
  return { kind: "testCtx" };
2438
2931
  }
2439
2932
  // node:test's MockFunctionContext<F> and MockFunctionCall<F>: compiler
2440
2933
  // records built from F (mock-shapes.ts). Mock<F> then maps as the hybrid
2441
2934
  // { %call: F, mock } record through mapHybridCallableIntersection.
2442
- if ((psym?.name === "MockFunctionContext" || psym?.name === "MockFunctionCall") &&
2443
- checker
2444
- .declarationsOf(psym)
2445
- .some((d) => ts.isInterfaceDeclaration(d) &&
2446
- ctx.isStdlibFile(d.getSourceFile()) &&
2935
+ if (((psym !== undefined && ts.symbolName(psym) === "MockFunctionContext") ||
2936
+ (psym !== undefined && ts.symbolName(psym) === "MockFunctionCall")) &&
2937
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
2938
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2447
2939
  isDeclaredInAmbientModule(d, "test"))) {
2448
2940
  const fnTs = checker.getTypeArguments(widened)[0];
2449
2941
  const fn = fnTs ? mapType(fnTs, ctx) : null;
2450
2942
  if (!fn || fn.kind !== "func")
2451
2943
  return null;
2452
- return psym.name === "MockFunctionContext"
2944
+ return ts.symbolName(psym) === "MockFunctionContext"
2453
2945
  ? mockContextType(fn, ctx)
2454
2946
  : mockCallRecordType(fn, ctx);
2455
2947
  }
@@ -2458,10 +2950,9 @@ function mapTypeInner(type, ctx) {
2458
2950
  // it to the runtime %Error hierarchy like the lib Error interfaces
2459
2951
  // above; optional metadata uses the same checked property view.
2460
2952
  // Provenance-checked like the rest.
2461
- if (psym?.name === "ErrnoException" &&
2462
- checker
2463
- .declarationsOf(psym)
2464
- .some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
2953
+ if (psym !== undefined &&
2954
+ ts.symbolName(psym) === "ErrnoException" &&
2955
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2465
2956
  return { kind: "object", className: "%Error" };
2466
2957
  }
2467
2958
  // http.Agent / https.Agent — the Agent VALUE is a checked-dynamic
@@ -2470,24 +2961,22 @@ function mapTypeInner(type, ctx) {
2470
2961
  // binding, parameter, or field carrying an Agent stays usable instead
2471
2962
  // of fencing at the declaration. Module-checked like the rest (https'
2472
2963
  // Agent extends http's; both live in their ambient modules).
2473
- if (psym?.name === "Agent" &&
2474
- checker
2475
- .declarationsOf(psym)
2476
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2477
- ctx.isStdlibFile(d.getSourceFile()) &&
2964
+ if (psym !== undefined &&
2965
+ ts.symbolName(psym) === "Agent" &&
2966
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2967
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2478
2968
  (isDeclaredInAmbientModule(d, "http") || isDeclaredInAmbientModule(d, "https")))) {
2479
2969
  return { kind: "dyn" };
2480
2970
  }
2481
2971
  // http.IncomingMessage / http.ServerResponse — module-checked like
2482
2972
  // net.Server (the names repeat nowhere today, but provenance stays the
2483
2973
  // rule).
2484
- if ((psym?.name === "IncomingMessage" || psym?.name === "ServerResponse") &&
2485
- checker
2486
- .declarationsOf(psym)
2487
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2488
- ctx.isStdlibFile(d.getSourceFile()) &&
2974
+ if (((psym !== undefined && ts.symbolName(psym) === "IncomingMessage") ||
2975
+ (psym !== undefined && ts.symbolName(psym) === "ServerResponse")) &&
2976
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2977
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2489
2978
  isDeclaredInAmbientModule(d, "http"))) {
2490
- return psym.name === "IncomingMessage" ? { kind: "httpReq" } : { kind: "httpRes" };
2979
+ return ts.symbolName(psym) === "IncomingMessage" ? { kind: "httpReq" } : { kind: "httpRes" };
2491
2980
  }
2492
2981
  // http2's compatibility surface (the allowHTTP1 lowering): the secure
2493
2982
  // server IS a net server (listen/close/address/emit ride the same
@@ -2497,17 +2986,15 @@ function mapTypeInner(type, ctx) {
2497
2986
  // ServerResponse surface. h2-only members (stream, session) fence per
2498
2987
  // member at their use sites (lower-server.ts). Module-checked like the
2499
2988
  // rest.
2500
- if ((psym?.name === "Http2SecureServer" ||
2501
- psym?.name === "Http2ServerRequest" ||
2502
- psym?.name === "Http2ServerResponse") &&
2503
- checker
2504
- .declarationsOf(psym)
2505
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2506
- ctx.isStdlibFile(d.getSourceFile()) &&
2989
+ if (((psym !== undefined && ts.symbolName(psym) === "Http2SecureServer") ||
2990
+ (psym !== undefined && ts.symbolName(psym) === "Http2ServerRequest") ||
2991
+ (psym !== undefined && ts.symbolName(psym) === "Http2ServerResponse")) &&
2992
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2993
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2507
2994
  isDeclaredInAmbientModule(d, "http2"))) {
2508
- return psym.name === "Http2SecureServer"
2995
+ return ts.symbolName(psym) === "Http2SecureServer"
2509
2996
  ? { kind: "netServer" }
2510
- : psym.name === "Http2ServerRequest"
2997
+ : ts.symbolName(psym) === "Http2ServerRequest"
2511
2998
  ? { kind: "httpReq" }
2512
2999
  : { kind: "httpRes" };
2513
3000
  }
@@ -2515,30 +3002,27 @@ function mapTypeInner(type, ctx) {
2515
3002
  // like the secure one; sessions and streams are first-class handle
2516
3003
  // kinds (client and server flavors share a kind — the runtime handle
2517
3004
  // carries the role). Module-checked like the rest.
2518
- if ((psym?.name === "Http2Server" ||
2519
- psym?.name === "Http2Session" ||
2520
- psym?.name === "ClientHttp2Session" ||
2521
- psym?.name === "ServerHttp2Session" ||
2522
- psym?.name === "ClientHttp2Stream" ||
2523
- psym?.name === "ServerHttp2Stream") &&
2524
- checker
2525
- .declarationsOf(psym)
2526
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2527
- ctx.isStdlibFile(d.getSourceFile()) &&
3005
+ if (((psym !== undefined && ts.symbolName(psym) === "Http2Server") ||
3006
+ (psym !== undefined && ts.symbolName(psym) === "Http2Session") ||
3007
+ (psym !== undefined && ts.symbolName(psym) === "ClientHttp2Session") ||
3008
+ (psym !== undefined && ts.symbolName(psym) === "ServerHttp2Session") ||
3009
+ (psym !== undefined && ts.symbolName(psym) === "ClientHttp2Stream") ||
3010
+ (psym !== undefined && ts.symbolName(psym) === "ServerHttp2Stream")) &&
3011
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
3012
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2528
3013
  isDeclaredInAmbientModule(d, "http2"))) {
2529
- return psym.name === "Http2Server"
3014
+ return ts.symbolName(psym) === "Http2Server"
2530
3015
  ? { kind: "netServer" }
2531
- : psym.name === "ClientHttp2Stream" || psym.name === "ServerHttp2Stream"
3016
+ : ts.symbolName(psym) === "ClientHttp2Stream" || ts.symbolName(psym) === "ServerHttp2Stream"
2532
3017
  ? { kind: "http2Stream" }
2533
3018
  : { kind: "http2Session" };
2534
3019
  }
2535
3020
  // http.ClientRequest (http.request/http.get results) — module-checked
2536
3021
  // like IncomingMessage.
2537
- if (psym?.name === "ClientRequest" &&
2538
- checker
2539
- .declarationsOf(psym)
2540
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2541
- ctx.isStdlibFile(d.getSourceFile()) &&
3022
+ if (psym !== undefined &&
3023
+ ts.symbolName(psym) === "ClientRequest" &&
3024
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
3025
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2542
3026
  isDeclaredInAmbientModule(d, "http"))) {
2543
3027
  return { kind: "httpClientReq" };
2544
3028
  }
@@ -2550,10 +3034,9 @@ function mapTypeInner(type, ctx) {
2550
3034
  // record) and ProcessEnv-typed parameters mappable. The fallback
2551
3035
  // declarations' anonymous env type takes the pureIndexShape path below
2552
3036
  // and interns the SAME shape.
2553
- if (psym?.name === "ProcessEnv" &&
2554
- checker
2555
- .declarationsOf(psym)
2556
- .some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
3037
+ if (psym !== undefined &&
3038
+ ts.symbolName(psym) === "ProcessEnv" &&
3039
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2557
3040
  const value = withUndefinedArm(STRING, ctx.unions);
2558
3041
  if (!value)
2559
3042
  return null;
@@ -2587,8 +3070,9 @@ function mapTypeInner(type, ctx) {
2587
3070
  if (isStdlibInterface("MapIterator") || isStdlibInterface("SetIterator"))
2588
3071
  return DYN;
2589
3072
  // Array iterators (`list.values()` and friends) are generators over the
2590
- // live array: each step reads the current length and element.
2591
- if (isStdlibInterface("ArrayIterator")) {
3073
+ // live array: each step reads the current length and element. String
3074
+ // iterators (`s[Symbol.iterator]()`) are generators over the code points.
3075
+ if (isStdlibInterface("ArrayIterator") || isStdlibInterface("StringIterator")) {
2592
3076
  const arg = checker.getTypeArguments(widened)[0];
2593
3077
  const yieldT = arg ? mapType(arg, ctx) : null;
2594
3078
  if (!yieldT || yieldT.kind === "void" || isUnitType(yieldT))
@@ -2623,7 +3107,10 @@ function mapTypeInner(type, ctx) {
2623
3107
  isStdlibInterface("IterableIterator") ||
2624
3108
  // An Iterator<T> annotation holds a single-pass iterator object: a
2625
3109
  // generator, or a native iterator adapted into one.
2626
- isStdlibInterface("Iterator")) {
3110
+ isStdlibInterface("Iterator") ||
3111
+ // IteratorObject<T> is what the iterator helpers return: a helper
3112
+ // generator over its source (containers/iterator-helpers.ts).
3113
+ isStdlibInterface("IteratorObject")) {
2627
3114
  const args = checker.getTypeArguments(widened);
2628
3115
  const channels = genChannels(args[0], args[1], args[2], ctx);
2629
3116
  if (!channels)
@@ -2644,10 +3131,9 @@ function mapTypeInner(type, ctx) {
2644
3131
  // g.next()` binds without an annotation and reads flow.
2645
3132
  {
2646
3133
  const alias = widened.getAliasSymbol();
2647
- if (alias?.name === "IteratorResult" &&
2648
- checker
2649
- .declarationsOf(alias)
2650
- .some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
3134
+ if (alias !== undefined &&
3135
+ ts.symbolName(alias) === "IteratorResult" &&
3136
+ alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2651
3137
  const targs = widened.getAliasTypeArguments() ?? [];
2652
3138
  const channels = genChannels(targs[0], targs[1], undefined, ctx);
2653
3139
  if (!channels)
@@ -2745,12 +3231,12 @@ function mapTypeInner(type, ctx) {
2745
3231
  ];
2746
3232
  const fields = [];
2747
3233
  for (const property of checker.getPropertiesOfType(widened)) {
2748
- if (!known.includes(property.name))
3234
+ if (!known.includes(ts.symbolName(property)))
2749
3235
  return null;
2750
3236
  const type = mapType(checker.getTypeOfSymbol(property), ctx);
2751
3237
  if (!type)
2752
3238
  return null;
2753
- fields.push({ name: property.name, type });
3239
+ fields.push({ name: ts.symbolName(property), type });
2754
3240
  }
2755
3241
  const order = fields.map((field) => field.name);
2756
3242
  fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
@@ -2758,23 +3244,21 @@ function mapTypeInner(type, ctx) {
2758
3244
  }
2759
3245
  // Filesystem options are data records. Keep their declared optional fields
2760
3246
  // instead of allowing arbitrary standard-library interfaces into records.
2761
- if ((psym?.name === "FileReadOptions" ||
2762
- psym?.name === "ReadOptions" ||
2763
- psym?.name === "ReadOptionsWithBuffer" ||
2764
- psym?.name === "WriteOptions") &&
2765
- checker
2766
- .declarationsOf(psym)
2767
- .some((d) => ts.isInterfaceDeclaration(d) &&
2768
- ctx.isStdlibFile(d.getSourceFile()) &&
3247
+ if (((psym !== undefined && ts.symbolName(psym) === "FileReadOptions") ||
3248
+ (psym !== undefined && ts.symbolName(psym) === "ReadOptions") ||
3249
+ (psym !== undefined && ts.symbolName(psym) === "ReadOptionsWithBuffer") ||
3250
+ (psym !== undefined && ts.symbolName(psym) === "WriteOptions")) &&
3251
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
3252
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2769
3253
  (isDeclaredInAmbientModule(d, "fs/promises") || isDeclaredInAmbientModule(d, "fs")))) {
2770
3254
  const fields = [];
2771
3255
  for (const property of checker.getPropertiesOfType(widened)) {
2772
- if (!["buffer", "offset", "length", "position"].includes(property.name))
3256
+ if (!["buffer", "offset", "length", "position"].includes(ts.symbolName(property)))
2773
3257
  return null;
2774
3258
  const type = mapType(checker.getTypeOfSymbol(property), ctx);
2775
3259
  if (!type)
2776
3260
  return null;
2777
- fields.push({ name: property.name, type });
3261
+ fields.push({ name: ts.symbolName(property), type });
2778
3262
  }
2779
3263
  const order = fields.map((field) => field.name);
2780
3264
  fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
@@ -2784,26 +3268,24 @@ function mapTypeInner(type, ctx) {
2784
3268
  // null-prototype objects returned by FileHandle.read/write. The native
2785
3269
  // record does not model the prototype (unobservable through the lowered
2786
3270
  // surface); it preserves the caller buffer/string by reference.
2787
- if ((psym?.name === "FileReadResult" ||
2788
- psym?.name === "FileWriteResult" ||
2789
- psym?.name === "FileReadvResult" ||
2790
- psym?.name === "FileWritevResult" ||
2791
- psym?.name === "ReadVResult" ||
2792
- psym?.name === "WriteVResult") &&
2793
- checker
2794
- .declarationsOf(psym)
2795
- .some((d) => ts.isInterfaceDeclaration(d) &&
2796
- ctx.isStdlibFile(d.getSourceFile()) &&
3271
+ if (((psym !== undefined && ts.symbolName(psym) === "FileReadResult") ||
3272
+ (psym !== undefined && ts.symbolName(psym) === "FileWriteResult") ||
3273
+ (psym !== undefined && ts.symbolName(psym) === "FileReadvResult") ||
3274
+ (psym !== undefined && ts.symbolName(psym) === "FileWritevResult") ||
3275
+ (psym !== undefined && ts.symbolName(psym) === "ReadVResult") ||
3276
+ (psym !== undefined && ts.symbolName(psym) === "WriteVResult")) &&
3277
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
3278
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2797
3279
  (isDeclaredInAmbientModule(d, "fs/promises") ||
2798
- ((psym.name === "ReadVResult" || psym.name === "WriteVResult") &&
3280
+ ((ts.symbolName(psym) === "ReadVResult" || ts.symbolName(psym) === "WriteVResult") &&
2799
3281
  isDeclaredInAmbientModule(d, "fs"))))) {
2800
3282
  const args = checker.getTypeArguments(widened);
2801
3283
  if (args.length !== 1)
2802
3284
  return null;
2803
- const vector = psym.name === "FileReadvResult" ||
2804
- psym.name === "FileWritevResult" ||
2805
- psym.name === "ReadVResult" ||
2806
- psym.name === "WriteVResult";
3285
+ const vector = ts.symbolName(psym) === "FileReadvResult" ||
3286
+ ts.symbolName(psym) === "FileWritevResult" ||
3287
+ ts.symbolName(psym) === "ReadVResult" ||
3288
+ ts.symbolName(psym) === "WriteVResult";
2807
3289
  const emptyVector = vector &&
2808
3290
  checker.isArrayType(args[0]) &&
2809
3291
  (checker.getTypeArguments(args[0])[0].flags & ts.TypeFlags.Never) !== 0;
@@ -2814,9 +3296,9 @@ function mapTypeInner(type, ctx) {
2814
3296
  : !(payload.kind === "string" || (payload.kind === "bytes" && payload.elem === "u8")))) {
2815
3297
  return null;
2816
3298
  }
2817
- const count = psym.name === "FileReadResult" ||
2818
- psym.name === "FileReadvResult" ||
2819
- psym.name === "ReadVResult"
3299
+ const count = ts.symbolName(psym) === "FileReadResult" ||
3300
+ ts.symbolName(psym) === "FileReadvResult" ||
3301
+ ts.symbolName(psym) === "ReadVResult"
2820
3302
  ? "bytesRead"
2821
3303
  : "bytesWritten";
2822
3304
  const payloadName = vector ? "buffers" : "buffer";
@@ -2842,11 +3324,10 @@ function mapTypeInner(type, ctx) {
2842
3324
  // encoding:'buffer' readdir form has no lowering); the shipped fallback
2843
3325
  // declares it concrete (an interface; @types/node uses a class — both
2844
3326
  // provenance-checked, the Buffer/URL pattern).
2845
- if (psym?.name === "Dirent" &&
2846
- checker
2847
- .declarationsOf(psym)
2848
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2849
- ctx.isStdlibFile(d.getSourceFile()))) {
3327
+ if (psym !== undefined &&
3328
+ ts.symbolName(psym) === "Dirent" &&
3329
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
3330
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2850
3331
  const args = checker.getTypeArguments(widened);
2851
3332
  if (args.length > 1)
2852
3333
  return null;
@@ -2884,15 +3365,13 @@ function mapTypeInner(type, ctx) {
2884
3365
  shapeId: ctx.shapes.intern(["idle", "irq", "nice", "sys", "user"].map((name) => ({ name, type: F64 })), false, undefined, ["user", "nice", "sys", "idle", "irq"]),
2885
3366
  });
2886
3367
  if (psym &&
2887
- checker
2888
- .declarationsOf(psym)
2889
- .some((d) => ts.isTypeLiteralNode(d) &&
3368
+ psym.declarations.some((d) => ts.isTypeLiteralNode(d) &&
2890
3369
  ts.isPropertySignature(d.parent) &&
2891
3370
  ts.isIdentifier(d.parent.name) &&
2892
3371
  d.parent.name.text === "times" &&
2893
3372
  ts.isInterfaceDeclaration(d.parent.parent) &&
2894
3373
  d.parent.parent.name.text === "CpuInfo" &&
2895
- ctx.isStdlibFile(d.getSourceFile())))
3374
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
2896
3375
  return cpuTimes();
2897
3376
  if (isStdlibInterface("CpuInfo")) {
2898
3377
  const times = cpuTimes();
@@ -2906,7 +3385,7 @@ function mapTypeInner(type, ctx) {
2906
3385
  };
2907
3386
  }
2908
3387
  if (isStdlibInterface("ParsedPath") || isStdlibInterface("FormatInputPathObject")) {
2909
- const field = psym.name === "ParsedPath" ? STRING : withUndefinedArm(STRING, ctx.unions);
3388
+ const field = ts.symbolName(psym) === "ParsedPath" ? STRING : withUndefinedArm(STRING, ctx.unions);
2910
3389
  if (!field)
2911
3390
  return null;
2912
3391
  return {
@@ -2936,26 +3415,40 @@ function mapTypeInner(type, ctx) {
2936
3415
  ], false, undefined, ["uid", "gid", "username", "homedir", "shell"]),
2937
3416
  };
2938
3417
  }
2939
- // The promisified exec/execFile result `{ stdout: string; stderr: string }`:
2940
- // an anonymous type literal (@types/node's __promisify__ overloads in
2941
- // child_process, the shipped fallback's promisify overloads in util),
2942
- // so it maps by provenance and exact shape, interned as the
2943
- // %execFileAsync/%execAsync helpers build it. Node builds the object as
2944
- // { stdout, stderr }. The Buffer-typed literals do not match and stay
3418
+ // The promisified exec/execFile result `{ stdout: string; stderr: string }`
3419
+ // and the promisified dns.lookupService result `{ hostname: string;
3420
+ // service: string }`: anonymous type literals (@types/node's
3421
+ // __promisify__ overloads in child_process and dns, the shipped
3422
+ // fallback's promisify overloads in util), so they map by provenance and
3423
+ // exact shape. The exec result is interned as the %execFileAsync/
3424
+ // %execAsync helpers build it; Node builds { stdout, stderr } and
3425
+ // { hostname, service }. The Buffer-typed literals do not match and stay
2945
3426
  // unmapped.
2946
3427
  if (psym &&
2947
- checker
2948
- .declarationsOf(psym)
2949
- .some((d) => ts.isTypeLiteralNode(d) &&
2950
- ctx.isStdlibFile(d.getSourceFile()) &&
2951
- (isDeclaredInAmbientModule(d, "child_process") || isDeclaredInAmbientModule(d, "util")))) {
3428
+ psym.declarations.some((d) => ts.isTypeLiteralNode(d) &&
3429
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
3430
+ (isDeclaredInAmbientModule(d, "child_process") ||
3431
+ isDeclaredInAmbientModule(d, "util") ||
3432
+ isDeclaredInAmbientModule(d, "dns")))) {
2952
3433
  const props = checker.getPropertiesOfType(widened);
2953
- if (props.length === 2 &&
2954
- props.every((p) => (p.name === "stdout" || p.name === "stderr") &&
2955
- (p.flags & ts.SymbolFlags.Optional) === 0 &&
2956
- (checker.getTypeOfSymbol(p).flags & ts.TypeFlags.String) !== 0) &&
2957
- props[0].name !== props[1].name) {
3434
+ const names = props.length === 2 &&
3435
+ props.every((p) => (p.flags & ts.SymbolFlags.Optional) === 0 &&
3436
+ (checker.getTypeOfSymbol(p).flags & ts.TypeFlags.String) !== 0)
3437
+ ? props
3438
+ .map((p) => ts.symbolName(p))
3439
+ .sort()
3440
+ .join(",")
3441
+ : "";
3442
+ if (names === "stderr,stdout")
2958
3443
  return { kind: "record", shapeId: execResultShape(ctx.shapes) };
3444
+ if (names === "hostname,service") {
3445
+ return {
3446
+ kind: "record",
3447
+ shapeId: ctx.shapes.intern([
3448
+ { name: "hostname", type: STRING },
3449
+ { name: "service", type: STRING },
3450
+ ], false, undefined, ["hostname", "service"]),
3451
+ };
2959
3452
  }
2960
3453
  }
2961
3454
  // crypto.X509Certificate — the Dirent-style data record: THREE visible
@@ -2965,11 +3458,10 @@ function mapTypeInner(type, ctx) {
2965
3458
  // `declare module "crypto"`, the shipped fallback mirrors it.
2966
3459
  // JSON.stringify of one shows the three fields where Node's
2967
3460
  // internal-slot object shows {} — the Dirent %dtype edge's cousin.
2968
- if (psym?.name === "X509Certificate" &&
2969
- checker
2970
- .declarationsOf(psym)
2971
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2972
- ctx.isStdlibFile(d.getSourceFile()) &&
3461
+ if (psym !== undefined &&
3462
+ ts.symbolName(psym) === "X509Certificate" &&
3463
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
3464
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
2973
3465
  isDeclaredInAmbientModule(d, "crypto"))) {
2974
3466
  return {
2975
3467
  kind: "record",
@@ -2988,16 +3480,31 @@ function mapTypeInner(type, ctx) {
2988
3480
  // record (util.inspect names the class from entryType, like Node).
2989
3481
  // @types/node declares the classes in perf_hooks and global interfaces
2990
3482
  // over them; the shipped fallback declares the classes.
2991
- if ((psym?.name === "PerformanceEntry" ||
2992
- psym?.name === "PerformanceMark" ||
2993
- psym?.name === "PerformanceMeasure") &&
2994
- checker
2995
- .declarationsOf(psym)
2996
- .some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
2997
- ctx.isStdlibFile(d.getSourceFile()))) {
3483
+ if (((psym !== undefined && ts.symbolName(psym) === "PerformanceEntry") ||
3484
+ (psym !== undefined && ts.symbolName(psym) === "PerformanceMark") ||
3485
+ (psym !== undefined && ts.symbolName(psym) === "PerformanceMeasure")) &&
3486
+ psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
3487
+ ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
2998
3488
  return { kind: "record", shapeId: perfEntryShape(ctx.shapes, ctx.unions) };
2999
3489
  }
3000
3490
  // readline's getCursorPos() record, in Node's key order ({ cols, rows }).
3491
+ // perf_hooks' EventLoopUtilization (performance.eventLoopUtilization's
3492
+ // result): a plain data record in Node's key order.
3493
+ if (isStdlibInterface("EventLoopUtilization")) {
3494
+ return {
3495
+ kind: "record",
3496
+ shapeId: ctx.shapes.intern([
3497
+ { name: "active", type: F64 },
3498
+ { name: "idle", type: F64 },
3499
+ { name: "utilization", type: F64 },
3500
+ ], false, undefined, ["idle", "active", "utilization"]),
3501
+ };
3502
+ }
3503
+ // monitorEventLoopDelay's IntervalHistogram: a numeric handle into the
3504
+ // runtime's histogram table, like a timer handle. Its members lower over
3505
+ // the handle (builtins/performance.ts).
3506
+ if (isStdlibInterface("IntervalHistogram"))
3507
+ return F64;
3001
3508
  if (isStdlibInterface("CursorPos")) {
3002
3509
  return {
3003
3510
  kind: "record",
@@ -3015,6 +3522,29 @@ function mapTypeInner(type, ctx) {
3015
3522
  shapeId: ctx.shapes.intern([...names].sort().map((name) => ({ name, type: F64 })), false, undefined, names),
3016
3523
  };
3017
3524
  }
3525
+ // v8.getHeapStatistics()'s record, in Node's key order (builtins/v8.ts).
3526
+ if (isStdlibInterface("HeapInfo")) {
3527
+ const names = [
3528
+ "total_heap_size",
3529
+ "total_heap_size_executable",
3530
+ "total_physical_size",
3531
+ "total_available_size",
3532
+ "used_heap_size",
3533
+ "heap_size_limit",
3534
+ "malloced_memory",
3535
+ "peak_malloced_memory",
3536
+ "does_zap_garbage",
3537
+ "number_of_native_contexts",
3538
+ "number_of_detached_contexts",
3539
+ "total_global_handles_size",
3540
+ "used_global_handles_size",
3541
+ "external_memory",
3542
+ ];
3543
+ return {
3544
+ kind: "record",
3545
+ shapeId: ctx.shapes.intern([...names].sort().map((name) => ({ name, type: F64 })), false, undefined, names),
3546
+ };
3547
+ }
3018
3548
  // process.cpuUsage()/threadCpuUsage()'s {user, system} microsecond
3019
3549
  // record and resourceUsage()'s getrusage record — stdlib data
3020
3550
  // interfaces interned explicitly (the RemoteInfo pattern; declared
@@ -3073,7 +3603,7 @@ function mapTypeInner(type, ctx) {
3073
3603
  // over a row answers exactly Node.
3074
3604
  if (isStdlibInterface("NetworkInterfaceInfoIPv4") ||
3075
3605
  isStdlibInterface("NetworkInterfaceInfoIPv6")) {
3076
- const v6 = psym.name === "NetworkInterfaceInfoIPv6";
3606
+ const v6 = ts.symbolName(psym) === "NetworkInterfaceInfoIPv6";
3077
3607
  const cidrArms = [NULL_T, STRING].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
3078
3608
  const cidr = { kind: "union", unionId: ctx.unions.intern(cidrArms) };
3079
3609
  const scopeid = v6 ? F64 : withUndefinedArm(F64, ctx.unions);
@@ -3173,146 +3703,8 @@ function mapTypeInner(type, ctx) {
3173
3703
  return hybrid;
3174
3704
  }
3175
3705
  const callSigs = checker.getCallSignatures(widened);
3176
- if (callSigs.length === 1) {
3177
- const sig = callSigs[0];
3178
- if (sig.getTypeParameters().length)
3179
- return null;
3180
- // A SYNTHESIZED rest param (tsc's JS inference for a function body
3181
- // reading `arguments` — `(...args: any[]) => any` whose args symbol
3182
- // has no declaration): the dotDotDot check below can't see it, and a
3183
- // fixed-arity func mapping would LIE about the value's calling
3184
- // convention. Detected by the param-count mismatch against the
3185
- // signature's own declaration, excluding an erased `this` parameter.
3186
- {
3187
- const sigDecl = checker.signatureDeclaration(sig);
3188
- const declParams = sigDecl !== undefined && ts.isFunctionLike(sigDecl) ? sigDecl.parameters : undefined;
3189
- if (declParams !== undefined &&
3190
- runtimeParameterCount(declParams) !== sig.getParameters().length) {
3191
- return null;
3192
- }
3193
- // tsgo never SYNTHESIZES that rest param into the inferred signature
3194
- // (5.9.3 did — the count mismatch above was the whole detector
3195
- // there), so the declaration's own body answers directly.
3196
- if (sigDecl !== undefined && ts.isFunctionLike(sigDecl) && bodyReadsArguments(sigDecl)) {
3197
- return null;
3198
- }
3199
- }
3200
- const params = [];
3201
- let typedRest = false;
3202
- for (const p of sig.getParameters()) {
3203
- const decl = checker.valueDeclarationOf(p);
3204
- const rest = decl !== undefined && ts.isParameter(decl) && decl.dotDotDotToken !== undefined;
3205
- // arity ABI selected by lambdaSignature. Treating an inferred any[]
3206
- // declaration as a typed packed-array closure would bypass its boxed
3207
- // spread/error semantics and change coverage classification.
3208
- if (rest && decl !== undefined && isJsSourceFile(decl.getSourceFile()))
3209
- return null;
3210
- const optional = decl !== undefined &&
3211
- ts.isParameter(decl) &&
3212
- (decl.questionToken !== undefined || decl.initializer !== undefined);
3213
- let pt = mapType(checker.getTypeOfSymbol(p), ctx);
3214
- if (decl &&
3215
- ts.isParameter(decl) &&
3216
- ts.isSetAccessorDeclaration(decl.parent) &&
3217
- isJsSourceFile(decl.getSourceFile()))
3218
- pt = DYN;
3219
- // An inferred JavaScript binding pattern consumes an iterable; it
3220
- // does not require the caller's array to have exactly this length.
3221
- const executor = decl && ts.isParameter(decl) ? decl.parent : null;
3222
- const construction = executor?.parent;
3223
- const constructorSymbol = construction && ts.isNewExpression(construction)
3224
- ? checker.getSymbolAtLocation(construction.expression)
3225
- : undefined;
3226
- const nativeExecutor = executor &&
3227
- (ts.isArrowFunction(executor) || ts.isFunctionExpression(executor)) &&
3228
- construction &&
3229
- ts.isNewExpression(construction) &&
3230
- construction.arguments?.[0] === executor &&
3231
- ts.isIdentifier(construction.expression) &&
3232
- construction.expression.text === "Promise" &&
3233
- constructorSymbol &&
3234
- checker
3235
- .declarationsOf(constructorSymbol)
3236
- .some((site) => ctx.isStdlibFile(site.getSourceFile()));
3237
- if (!nativeExecutor &&
3238
- decl &&
3239
- ts.isParameter(decl) &&
3240
- !decl.dotDotDotToken &&
3241
- !ts.isSetAccessorDeclaration(decl.parent) &&
3242
- isJsSourceFile(decl.getSourceFile()) &&
3243
- !decl.type &&
3244
- !/@(?:param|type)\b/.test(decl.getSourceFile().text.slice(decl.parent?.pos ?? decl.pos, decl.getStart())))
3245
- pt = DYN;
3246
- if (pt)
3247
- pt = jsOpenObjectType(decl, pt, ctx.shapes, ctx.unions);
3248
- // Belt and braces for non-strict type worlds: an optional param's
3249
- // ABI slot is always the undefined-armed union (strictNullChecks
3250
- // already spells it that way; arm it here if the world didn't).
3251
- if (optional && pt && pt.kind !== "void" && pt.kind !== "dyn") {
3252
- const armed = withUndefinedArm(pt, ctx.unions);
3253
- if (!armed)
3254
- return null;
3255
- pt = armed;
3256
- }
3257
- if (!pt)
3258
- return null;
3259
- if (rest) {
3260
- if (pt.kind !== "array")
3261
- return null;
3262
- typedRest = true;
3263
- }
3264
- // `(value: void) => void` (Promise<void>'s resolve) is callable with
3265
- // no arguments — a void param is dropped, not a mapping failure.
3266
- if (pt.kind === "void")
3267
- continue;
3268
- params.push(pt);
3269
- }
3270
- const retT = checker.getReturnTypeOfSignature(sig);
3271
- // `() => never` (a throw-only lambda's inferred type) is assignable to
3272
- // `() => void` and its calls never produce a value — map the return
3273
- // like declaredReturnType does for declarations. JS null/undefined
3274
- // returns can read mutable fields, so callable values use the same
3275
- // checked-native return ABI as their implementations.
3276
- const sigDecl = checker.signatureDeclaration(sig);
3277
- const jsUnitReturn = sigDecl !== undefined &&
3278
- isJsSourceFile(sigDecl.getSourceFile()) &&
3279
- (retT.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0;
3280
- let ret = jsUnitReturn || (retT.flags & ts.TypeFlags.Any) !== 0
3281
- ? DYN
3282
- : retT.flags & ts.TypeFlags.Never
3283
- ? VOID
3284
- : mapType(retT, ctx);
3285
- if (sigDecl && ts.isGetAccessorDeclaration(sigDecl) && isJsSourceFile(sigDecl.getSourceFile()))
3286
- ret = DYN;
3287
- if (sigDecl && isJsSourceFile(sigDecl.getSourceFile()) && ret?.kind === "array")
3288
- ret = DYN;
3289
- if (sigDecl &&
3290
- ts.isFunctionLike(sigDecl) &&
3291
- isJsSourceFile(sigDecl.getSourceFile()) &&
3292
- !sigDecl.type &&
3293
- !/@returns?\b/.test(sigDecl.getSourceFile().text.slice(sigDecl.pos, sigDecl.getStart())) &&
3294
- ret?.kind === "record")
3295
- ret = DYN;
3296
- if (sigDecl &&
3297
- ts.isFunctionLike(sigDecl) &&
3298
- isJsSourceFile(sigDecl.getSourceFile()) &&
3299
- !sigDecl.type &&
3300
- !/@returns?\b/.test(sigDecl.getSourceFile().text.slice(sigDecl.pos, sigDecl.getStart())) &&
3301
- (ret?.kind === "date" ||
3302
- (ret?.kind === "union" &&
3303
- ctx.unions.get(ret.unionId)?.arms.some((arm) => arm.kind === "func"))))
3304
- ret = DYN;
3305
- if (ret &&
3306
- sigDecl &&
3307
- isJsSourceFile(sigDecl.getSourceFile()) &&
3308
- functionCanReturnUndefined(sigDecl))
3309
- ret = withUndefinedArm(ret, ctx.unions) ?? ret;
3310
- if (!ret)
3311
- return null;
3312
- return typedRest
3313
- ? { kind: "func", params, ret, rest: true, restAbi: "typed" }
3314
- : funcOf(params, ret);
3315
- }
3706
+ if (callSigs.length === 1)
3707
+ return mapCallSignature(callSigs[0], ctx);
3316
3708
  // Records: object types whose members are all data properties (shorthand
3317
3709
  // methods in type position count — they're func-typed fields) with
3318
3710
  // mappable types; no call/construct signatures, no index signatures, not
@@ -3349,10 +3741,8 @@ function mapTypeInner(type, ctx) {
3349
3741
  if (flags & ts.TypeFlags.Object &&
3350
3742
  callSigs.length === 0 &&
3351
3743
  psym !== undefined &&
3352
- checker.declarationsOf(psym).length > 0 &&
3353
- checker
3354
- .declarationsOf(psym)
3355
- .every((d) => ts.isInterfaceDeclaration(d) && !ctx.isStdlibFile(d.getSourceFile()))) {
3744
+ psym.declarations.length > 0 &&
3745
+ psym.declarations.every((d) => ts.isInterfaceDeclaration(d) && !ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
3356
3746
  const CHILD_SURFACE = new Set([
3357
3747
  "pid",
3358
3748
  "exitCode",
@@ -3385,37 +3775,49 @@ function mapTypeInner(type, ctx) {
3385
3775
  const props = checker.getPropertiesOfType(widened);
3386
3776
  let core = 0;
3387
3777
  const childMemberType = (p) => {
3388
- if (["kill", "on", "once", "off", "removeListener", "unref", "ref"].includes(p.name)) {
3778
+ if (["kill", "on", "once", "off", "removeListener", "unref", "ref"].includes(ts.symbolName(p))) {
3389
3779
  return checker.getCallSignatures(checker.getTypeOfSymbol(p)).length > 0;
3390
3780
  }
3391
- const expected = p.name === "stdout" || p.name === "stderr"
3781
+ const expected = ts.symbolName(p) === "stdout" || ts.symbolName(p) === "stderr"
3392
3782
  ? "childStream"
3393
- : p.name === "stdin"
3783
+ : ts.symbolName(p) === "stdin"
3394
3784
  ? "childWriter"
3395
- : p.name === "killed"
3785
+ : ts.symbolName(p) === "killed"
3396
3786
  ? "bool"
3397
3787
  : "f64";
3398
- const unit = p.name === "pid"
3788
+ const unit = ts.symbolName(p) === "pid"
3399
3789
  ? "undefinedT"
3400
- : p.name === "exitCode" ||
3401
- p.name === "stdin" ||
3402
- p.name === "stdout" ||
3403
- p.name === "stderr"
3790
+ : ts.symbolName(p) === "exitCode" ||
3791
+ ts.symbolName(p) === "stdin" ||
3792
+ ts.symbolName(p) === "stdout" ||
3793
+ ts.symbolName(p) === "stderr"
3404
3794
  ? "nullT"
3405
3795
  : null;
3406
3796
  const mapped = mapType(checker.getTypeOfSymbol(p), ctx);
3407
3797
  if (!mapped)
3408
3798
  return false;
3409
3799
  const arms = mapped.kind === "union" ? ctx.unions.get(mapped.unionId)?.arms : [mapped];
3800
+ // Under the general stream representation the stdio members are the
3801
+ // runtime stream classes.
3802
+ const isExpected = (arm) => arm.kind === expected ||
3803
+ (ctx.generalNodeStreams === true &&
3804
+ arm.kind === "object" &&
3805
+ ((expected === "childStream" && arm.className === "%Readable") ||
3806
+ (expected === "childWriter" && arm.className === "%Writable"))) ||
3807
+ // Checked-dynamic stream slots: `NodeJS.ReadableStream | null`
3808
+ // collapses to dyn (the reads still produce the bridged stream).
3809
+ (ctx.dynNodeStreams === true &&
3810
+ arm.kind === "dyn" &&
3811
+ (expected === "childStream" || expected === "childWriter"));
3410
3812
  return (arms !== undefined &&
3411
- arms.some((arm) => arm.kind === expected) &&
3412
- arms.every((arm) => arm.kind === expected || arm.kind === unit));
3813
+ arms.some(isExpected) &&
3814
+ arms.every((arm) => isExpected(arm) || arm.kind === unit));
3413
3815
  };
3414
3816
  const childShaped = props.length > 0 &&
3415
3817
  props.every((p) => {
3416
- if (!CHILD_SURFACE.has(p.name) || !childMemberType(p))
3818
+ if (!CHILD_SURFACE.has(ts.symbolName(p)) || !childMemberType(p))
3417
3819
  return false;
3418
- if (CHILD_CORE.has(p.name))
3820
+ if (CHILD_CORE.has(ts.symbolName(p)))
3419
3821
  core++;
3420
3822
  return true;
3421
3823
  });
@@ -3423,6 +3825,9 @@ function mapTypeInner(type, ctx) {
3423
3825
  return CHILD_T;
3424
3826
  }
3425
3827
  if (flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection) && callSigs.length === 0) {
3828
+ const viaMapped = mapBoundMappedType(widened, ctx);
3829
+ if (viaMapped)
3830
+ return viaMapped;
3426
3831
  const viaAlias = mapGenericUtilityAlias(widened, ctx);
3427
3832
  if (viaAlias)
3428
3833
  return viaAlias;
@@ -3556,7 +3961,7 @@ function mapTypeInner(type, ctx) {
3556
3961
  a.kind === "date" ||
3557
3962
  a.kind === "dyn" ||
3558
3963
  a.kind === "generator") ||
3559
- !unionContainerArmsOk(arms)) {
3964
+ !maybePromiseUnionOk(parts, arms, ctx)) {
3560
3965
  return null;
3561
3966
  }
3562
3967
  arms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
@@ -3582,28 +3987,247 @@ function mapTypeInner(type, ctx) {
3582
3987
  }
3583
3988
  return null;
3584
3989
  }
3585
- /** Retain a literal discriminator before widening erases its values. A
3586
- * structural match alone is insufficient: `{ kind: "loop", body: ... }`
3587
- * also fits a smaller `{ kind: "empty" }` record. Choosing that layout
3588
- * makes a later switch on kind read fields outside the allocated object.
3589
- *
3590
- * Require one common, required data property with finite literal values.
3591
- * Values may repeat within a single storage arm (several variants share a
3592
- * shape), but never select different arms. Non-record arms keep their
3593
- * ordinary kind checks. Types without an unambiguous discriminator retain
3990
+ /** One non-overloaded call signature's func type (mapTypeInner's
3991
+ * single-signature rule; erasedOverloadMemberType maps each overload of a
3992
+ * member through it). */
3993
+ function mapCallSignature(sig, ctx) {
3994
+ const { checker } = ctx;
3995
+ if (sig.getTypeParameters().length && ctx.erasingSignature !== sig)
3996
+ return null;
3997
+ // A SYNTHESIZED rest param (tsc's JS inference for a function body
3998
+ // reading `arguments` — `(...args: any[]) => any` whose args symbol
3999
+ // has no declaration): the dotDotDot check below can't see it, and a
4000
+ // fixed-arity func mapping would LIE about the value's calling
4001
+ // convention. Detected by the param-count mismatch against the
4002
+ // signature's own declaration, excluding an erased `this` parameter.
4003
+ {
4004
+ const sigDecl = sig.declaration;
4005
+ const declParams = sigDecl !== undefined && ts.isFunctionLike(sigDecl) ? sigDecl.parameters.nodes : undefined;
4006
+ if (declParams !== undefined &&
4007
+ runtimeParameterCount(declParams) !== sig.getParameters().length) {
4008
+ return null;
4009
+ }
4010
+ // tsgo never SYNTHESIZES that rest param into the inferred signature
4011
+ // (5.9.3 did — the count mismatch above was the whole detector
4012
+ // there), so the declaration's own body answers directly.
4013
+ if (sigDecl !== undefined && ts.isFunctionLike(sigDecl) && bodyReadsArguments(sigDecl)) {
4014
+ return null;
4015
+ }
4016
+ }
4017
+ const params = [];
4018
+ let typedRest = false;
4019
+ let dynRest = false;
4020
+ for (const p of sig.getParameters()) {
4021
+ const decl = p.valueDeclaration;
4022
+ const rest = decl !== undefined && ts.isParameter(decl) && decl.dotDotDotToken !== undefined;
4023
+ // arity ABI selected by lambdaSignature. Treating an inferred any[]
4024
+ // declaration as a typed packed-array closure would bypass its boxed
4025
+ // spread/error semantics and change coverage classification.
4026
+ if (rest && decl !== undefined && isJsSourceFile(ts.getSourceFileOfNode(decl)))
4027
+ return null;
4028
+ // A fixed-tuple rest (`...args: [A, B]`, `...args: Parameters<F>` over
4029
+ // a bound F) flattens to its positional parameters. Pattern rests keep
4030
+ // their packed-record ABI and stay unmapped as values.
4031
+ if (rest && decl !== undefined && ts.isParameter(decl) && ts.isIdentifier(decl.name)) {
4032
+ const elems = restTupleParamTypes(checker.getTypeOfSymbol(p), ctx);
4033
+ if (elems) {
4034
+ params.push(...elems);
4035
+ continue;
4036
+ }
4037
+ }
4038
+ const optional = decl !== undefined &&
4039
+ ts.isParameter(decl) &&
4040
+ (decl.questionToken !== undefined || decl.initializer !== undefined);
4041
+ let pt = mapType(checker.getTypeOfSymbol(p), ctx);
4042
+ // A parameter a TypeScript program types `any` takes whatever the
4043
+ // caller passes: the checked-dynamic slot, as an `any`-typed binding
4044
+ // already is (dynFallbackType). Declaration files keep their paths.
4045
+ // Only function declarations, spelled function types and lambda
4046
+ // parameters whose default is the only source of their type (`(n =
4047
+ // lookup() ?? 5) => ...` with an `any` lookup): other lambdas and
4048
+ // methods in object literals keep their existing checked-dynamic story.
4049
+ if (!pt &&
4050
+ !rest &&
4051
+ decl !== undefined &&
4052
+ ts.isParameter(decl) &&
4053
+ decl.parent !== undefined &&
4054
+ (ts.isFunctionDeclaration(decl.parent) ||
4055
+ ts.isFunctionTypeNode(decl.parent) ||
4056
+ ((ts.isArrowFunction(decl.parent) || ts.isFunctionExpression(decl.parent)) &&
4057
+ decl.initializer !== undefined &&
4058
+ decl.type === undefined &&
4059
+ !isJsSourceFile(ts.getSourceFileOfNode(decl)))) &&
4060
+ !ts.getSourceFileOfNode(decl).isDeclarationFile &&
4061
+ (checker.getTypeOfSymbol(p).flags & ts.TypeFlags.Any) !== 0)
4062
+ pt = DYN;
4063
+ if (decl &&
4064
+ ts.isParameter(decl) &&
4065
+ ts.isSetAccessorDeclaration(decl.parent) &&
4066
+ isJsSourceFile(ts.getSourceFileOfNode(decl)))
4067
+ pt = DYN;
4068
+ // An inferred JavaScript binding pattern consumes an iterable; it
4069
+ // does not require the caller's array to have exactly this length.
4070
+ const executor = decl && ts.isParameter(decl) ? decl.parent : null;
4071
+ const construction = executor?.parent;
4072
+ const constructorSymbol = construction && ts.isNewExpression(construction)
4073
+ ? checker.getSymbolAtLocation(construction.expression)
4074
+ : undefined;
4075
+ const nativeExecutor = executor &&
4076
+ (ts.isArrowFunction(executor) || ts.isFunctionExpression(executor)) &&
4077
+ construction &&
4078
+ ts.isNewExpression(construction) &&
4079
+ construction.arguments?.nodes[0] === executor &&
4080
+ ts.isIdentifier(construction.expression) &&
4081
+ construction.expression.text === "Promise" &&
4082
+ constructorSymbol &&
4083
+ constructorSymbol.declarations.some((site) => ctx.isStdlibFile(ts.getSourceFileOfNode(site)));
4084
+ if (!nativeExecutor &&
4085
+ decl &&
4086
+ ts.isParameter(decl) &&
4087
+ !decl.dotDotDotToken &&
4088
+ !ts.isSetAccessorDeclaration(decl.parent) &&
4089
+ isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
4090
+ !decl.type &&
4091
+ !/@(?:param|type)\b/.test(ts
4092
+ .getSourceFileOfNode(decl)
4093
+ .text.slice(decl.parent?.pos ?? decl.pos, ts.tokenStartOfNode(decl))))
4094
+ pt = DYN;
4095
+ // A DEFAULTED program-source parameter of a function, arrow or function
4096
+ // expression that the checker types `any` — a default under an
4097
+ // `(...args: any[]) => any` wrapper slot (`wrap((limit = 5) => ...)`),
4098
+ // where the contextual `any` wins over the default's type: its binding
4099
+ // is already the checked-dynamic kind inside the body
4100
+ // (dynFallbackType), so the callable's ABI slot is the same dyn value.
4101
+ // Other `any` parameters keep their existing paths (an object literal
4102
+ // holding such a callback stays a checked-dynamic object).
4103
+ if (pt === null &&
4104
+ !rest &&
4105
+ decl !== undefined &&
4106
+ ts.isParameter(decl) &&
4107
+ decl.initializer !== undefined &&
4108
+ (ts.isArrowFunction(decl.parent) ||
4109
+ ts.isFunctionExpression(decl.parent) ||
4110
+ ts.isFunctionDeclaration(decl.parent)) &&
4111
+ !ts.getSourceFileOfNode(decl).isDeclarationFile &&
4112
+ (checker.getTypeOfSymbol(p).flags & ts.TypeFlags.Any) !== 0)
4113
+ pt = DYN;
4114
+ if (pt)
4115
+ pt = jsOpenObjectType(decl, pt, ctx.shapes, ctx.unions);
4116
+ // Belt and braces for non-strict type worlds: an optional param's
4117
+ // ABI slot is always the undefined-armed union (strictNullChecks
4118
+ // already spells it that way; arm it here if the world didn't).
4119
+ if (optional && pt && pt.kind !== "void" && pt.kind !== "dyn") {
4120
+ const armed = withUndefinedArm(pt, ctx.unions);
4121
+ if (!armed)
4122
+ return null;
4123
+ pt = armed;
4124
+ }
4125
+ // `...args: unknown[]` / `...args: any[]` declared in program source:
4126
+ // the checked-dynamic variadic ABI (no typed slot; the callee's hidden
4127
+ // trailing dyn array receives every surplus argument, as for JS rest
4128
+ // params). Declaration files keep their existing paths: library
4129
+ // callback slots such as String#replace's `(substring, ...args: any[])`
4130
+ // have intrinsic lowerings that inspect the unmapped type.
4131
+ // node:test's default mock function type, `(...args: any[]) =>
4132
+ // undefined` (the type parameter default of mock.fn), takes the same
4133
+ // ABI: mock.fn() without an original records whatever its callers pass.
4134
+ if (rest &&
4135
+ decl !== undefined &&
4136
+ (!ts.getSourceFileOfNode(decl).isDeclarationFile ||
4137
+ isNodeTestDefaultFunctionParam(decl, ctx)) &&
4138
+ (pt?.kind === "dyn" || (!pt && isAnyArrayType(checker.getTypeOfSymbol(p), checker)))) {
4139
+ dynRest = true;
4140
+ continue;
4141
+ }
4142
+ if (!pt)
4143
+ return null;
4144
+ if (rest) {
4145
+ if (pt.kind !== "array")
4146
+ return null;
4147
+ typedRest = true;
4148
+ }
4149
+ // `(value: void) => void` (Promise<void>'s resolve) is callable with
4150
+ // no arguments — a void param is dropped, not a mapping failure.
4151
+ if (pt.kind === "void")
4152
+ continue;
4153
+ params.push(pt);
4154
+ }
4155
+ const retT = checker.getReturnTypeOfSignature(sig);
4156
+ // `() => never` (a throw-only lambda's inferred type) is assignable to
4157
+ // `() => void` and its calls never produce a value — map the return
4158
+ // like declaredReturnType does for declarations. JS null/undefined
4159
+ // returns can read mutable fields, so callable values use the same
4160
+ // checked-native return ABI as their implementations.
4161
+ const sigDecl = sig.declaration;
4162
+ const jsUnitReturn = sigDecl !== undefined &&
4163
+ isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
4164
+ (retT.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0;
4165
+ let ret = jsUnitReturn || (retT.flags & ts.TypeFlags.Any) !== 0
4166
+ ? DYN
4167
+ : retT.flags & ts.TypeFlags.Never
4168
+ ? VOID
4169
+ : mapType(retT, ctx);
4170
+ if (sigDecl &&
4171
+ ts.isGetAccessorDeclaration(sigDecl) &&
4172
+ isJsSourceFile(ts.getSourceFileOfNode(sigDecl)))
4173
+ ret = DYN;
4174
+ if (sigDecl && isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) && ret?.kind === "array")
4175
+ ret = DYN;
4176
+ if (sigDecl &&
4177
+ ts.isFunctionLike(sigDecl) &&
4178
+ isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
4179
+ !sigDecl.type &&
4180
+ !/@returns?\b/.test(ts.getSourceFileOfNode(sigDecl).text.slice(sigDecl.pos, ts.tokenStartOfNode(sigDecl))) &&
4181
+ ret?.kind === "record")
4182
+ ret = DYN;
4183
+ if (sigDecl &&
4184
+ ts.isFunctionLike(sigDecl) &&
4185
+ isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
4186
+ !sigDecl.type &&
4187
+ !/@returns?\b/.test(ts.getSourceFileOfNode(sigDecl).text.slice(sigDecl.pos, ts.tokenStartOfNode(sigDecl))) &&
4188
+ (ret?.kind === "date" ||
4189
+ (ret?.kind === "union" &&
4190
+ ctx.unions.get(ret.unionId)?.arms.some((arm) => arm.kind === "func"))))
4191
+ ret = DYN;
4192
+ if (ret &&
4193
+ sigDecl &&
4194
+ isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
4195
+ functionCanReturnUndefined(sigDecl))
4196
+ ret = withUndefinedArm(ret, ctx.unions) ?? ret;
4197
+ if (!ret)
4198
+ return null;
4199
+ return typedRest
4200
+ ? { kind: "func", params, ret, rest: true, restAbi: "typed" }
4201
+ : dynRest
4202
+ ? { kind: "func", params, ret, rest: true }
4203
+ : funcOf(params, ret);
4204
+ }
4205
+ /** Retain a literal discriminator before widening erases its values. A
4206
+ * structural match alone is insufficient: `{ kind: "loop", body: ... }`
4207
+ * also fits a smaller `{ kind: "empty" }` record. Choosing that layout
4208
+ * makes a later switch on kind read fields outside the allocated object.
4209
+ *
4210
+ * Require one common, required data property with finite literal values.
4211
+ * Values may repeat within a single storage arm (several variants share a
4212
+ * shape), but never select different arms. Non-record arms keep their
4213
+ * ordinary kind checks. Types without an unambiguous discriminator retain
3594
4214
  * their structural boundary behavior. */
3595
4215
  function unionDiscriminant(parts, arms, ctx) {
3596
4216
  if (arms.filter((arm) => arm.kind === "record").length < 2 || parts.length < 2)
3597
4217
  return undefined;
3598
4218
  const { checker } = ctx;
4219
+ // Tuple shapes keep positions only: their checker `length` literal has
4220
+ // no slot to compare (discriminantField refuses tuple shapes too).
4221
+ if (parts.some((part) => ctx.shapes.get(part.mapped.shapeId)?.tuple))
4222
+ return undefined;
3599
4223
  for (const candidate of checker.getPropertiesOfType(parts[0].source)) {
3600
- if (candidate.name.startsWith("__@"))
4224
+ if (ts.symbolName(candidate).startsWith("__@"))
3601
4225
  continue;
3602
4226
  const byTag = new Map();
3603
4227
  const owner = new Map();
3604
4228
  let complete = true;
3605
4229
  for (const part of parts) {
3606
- const prop = checker.getPropertyOfType(part.source, candidate.name);
4230
+ const prop = checker.getPropertyOfType(part.source, ts.symbolName(candidate));
3607
4231
  if (!prop ||
3608
4232
  prop.flags &
3609
4233
  (ts.SymbolFlags.Optional | ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) {
@@ -3634,7 +4258,7 @@ function unionDiscriminant(parts, arms, ctx) {
3634
4258
  }
3635
4259
  if (complete) {
3636
4260
  return {
3637
- field: candidate.name,
4261
+ field: ts.symbolName(candidate),
3638
4262
  cases: [...byTag]
3639
4263
  .sort(([a], [b]) => a - b)
3640
4264
  .map(([tag, values]) => ({
@@ -3667,9 +4291,9 @@ function mapClassView(type, ctx, seen = new Set()) {
3667
4291
  }
3668
4292
  else {
3669
4293
  const symbol = type.getSymbol();
3670
- const declarations = symbol ? checker.declarationsOf(symbol) : [];
4294
+ const declarations = symbol ? symbol.declarations : [];
3671
4295
  if (declarations.length === 0 ||
3672
- !declarations.every((decl) => ts.isInterfaceDeclaration(decl) && !ctx.isStdlibFile(decl.getSourceFile())))
4296
+ !declarations.every((decl) => ts.isInterfaceDeclaration(decl) && !ctx.isStdlibFile(ts.getSourceFileOfNode(decl))))
3673
4297
  return undefined;
3674
4298
  const target = type.isTypeReference() ? type.getTarget() : type;
3675
4299
  if (target === undefined || !target.isClassOrInterface())
@@ -3702,10 +4326,10 @@ function mapClassView(type, ctx, seen = new Set()) {
3702
4326
  let representation;
3703
4327
  for (const base of bases) {
3704
4328
  const symbol = base.getSymbol();
3705
- const declaration = symbol ? checker.valueDeclarationOf(symbol) : undefined;
4329
+ const declaration = symbol ? symbol.valueDeclaration : undefined;
3706
4330
  const classBase = declaration &&
3707
4331
  (ts.isClassDeclaration(declaration) || ts.isClassExpression(declaration)) &&
3708
- !declaration.getSourceFile().isDeclarationFile;
4332
+ !ts.getSourceFileOfNode(declaration).isDeclarationFile;
3709
4333
  const mapped = classBase ? mapType(base, viewCtx) : mapClassView(base, viewCtx, seen);
3710
4334
  if (mapped === null)
3711
4335
  return null;
@@ -3723,13 +4347,13 @@ function mapClassView(type, ctx, seen = new Set()) {
3723
4347
  checker.getIndexInfosOfType(type).length)
3724
4348
  return null;
3725
4349
  for (const property of checker.getPropertiesOfType(type)) {
3726
- const original = checker.getPropertyOfType(baseType, property.name);
4350
+ const original = checker.getPropertyOfType(baseType, ts.symbolName(property));
3727
4351
  if (!original)
3728
4352
  return null;
3729
4353
  if (original === property)
3730
4354
  continue;
3731
- const originalDeclarations = checker.declarationsOf(original);
3732
- const declarations = checker.declarationsOf(property);
4355
+ const originalDeclarations = original.declarations;
4356
+ const declarations = property.declarations;
3733
4357
  // Instantiating an inherited member can create a new symbol without
3734
4358
  // changing its declaration or ABI. Only refinements need validation.
3735
4359
  if (declarations.length > 0 &&
@@ -3764,9 +4388,9 @@ function mapCollectionView(type, ctx, seen = new Set()) {
3764
4388
  return null;
3765
4389
  const { checker } = ctx;
3766
4390
  const symbol = type.getSymbol();
3767
- const declarations = symbol ? checker.declarationsOf(symbol) : [];
4391
+ const declarations = symbol ? symbol.declarations : [];
3768
4392
  if (declarations.length === 0 ||
3769
- !declarations.every((decl) => ts.isInterfaceDeclaration(decl) && !ctx.isStdlibFile(decl.getSourceFile())))
4393
+ !declarations.every((decl) => ts.isInterfaceDeclaration(decl) && !ctx.isStdlibFile(ts.getSourceFileOfNode(decl))))
3770
4394
  return null;
3771
4395
  const target = type.getTarget();
3772
4396
  if (target === undefined ||
@@ -3807,21 +4431,17 @@ function mapCollectionView(type, ctx, seen = new Set()) {
3807
4431
  const base = bases[0];
3808
4432
  const baseSymbol = base.getSymbol();
3809
4433
  const native = baseSymbol &&
3810
- ["Map", "ReadonlyMap", "Set", "ReadonlySet"].includes(baseSymbol.name) &&
3811
- checker
3812
- .declarationsOf(baseSymbol)
3813
- .some((decl) => ts.isInterfaceDeclaration(decl) && ctx.isStdlibFile(decl.getSourceFile()));
4434
+ ["Map", "ReadonlyMap", "Set", "ReadonlySet"].includes(ts.symbolName(baseSymbol)) &&
4435
+ baseSymbol.declarations.some((decl) => ts.isInterfaceDeclaration(decl) && ctx.isStdlibFile(ts.getSourceFileOfNode(decl)));
3814
4436
  const mapped = native ? mapType(base, baseCtx) : mapCollectionView(base, baseCtx, seen);
3815
4437
  if (mapped?.kind !== "map" && mapped?.kind !== "set")
3816
4438
  return null;
3817
4439
  const hasType = funcOf([mapped.kind === "map" ? mapped.key : mapped.elem], BOOL);
3818
4440
  for (const property of checker.getPropertiesOfType(type)) {
3819
- const own = checker
3820
- .declarationsOf(property)
3821
- .filter((decl) => !ctx.isStdlibFile(decl.getSourceFile()));
4441
+ const own = property.declarations.filter((decl) => !ctx.isStdlibFile(ts.getSourceFileOfNode(decl)));
3822
4442
  if (own.length === 0)
3823
4443
  continue;
3824
- if (property.name !== "has" ||
4444
+ if (ts.symbolName(property) !== "has" ||
3825
4445
  property.flags & ts.SymbolFlags.Optional ||
3826
4446
  !own.every((decl) => decl.kind === ts.SyntaxKind.MethodSignature))
3827
4447
  return null;
@@ -3931,6 +4551,166 @@ function mapBoundIndexedAccess(type, ctx) {
3931
4551
  return null;
3932
4552
  return mapType(checker.getTypeOfSymbol(prop), ctx);
3933
4553
  }
4554
+ /** The standard library's `Parameters<F>` / `ReturnType<F>` over a type
4555
+ * parameter the current instantiation binds to a callable checker type:
4556
+ * that type's one call signature. Concrete arguments never reach here (the
4557
+ * checker evaluates those conditionals itself); generic bodies keep them
4558
+ * symbolic because their `infer` sits in a call signature. */
4559
+ function boundSignatureAlias(type, ctx) {
4560
+ const { checker, resolveTypeParamTs } = ctx;
4561
+ if (!resolveTypeParamTs)
4562
+ return null;
4563
+ const alias = type.getAliasSymbol();
4564
+ const aliasName = alias === undefined ? undefined : ts.symbolName(alias);
4565
+ if (!alias || (aliasName !== "Parameters" && aliasName !== "ReturnType"))
4566
+ return null;
4567
+ const aliasArgs = type.getAliasTypeArguments();
4568
+ const arg = aliasArgs[0];
4569
+ if (aliasArgs.length !== 1 || !arg || !(arg.flags & ts.TypeFlags.TypeParameter))
4570
+ return null;
4571
+ const isLibAlias = alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
4572
+ if (!isLibAlias)
4573
+ return null;
4574
+ const bound = resolveTypeParamTs(arg);
4575
+ if (!bound || bound.flags & ts.TypeFlags.TypeParameter)
4576
+ return null;
4577
+ const sigs = checker.getCallSignatures(bound);
4578
+ const sig = sigs[0];
4579
+ if (sigs.length !== 1 || !sig || sig.getTypeParameters().length > 0)
4580
+ return null;
4581
+ return { name: aliasName, sig };
4582
+ }
4583
+ /** The positional parameters of a signature as a fixed tuple: a trailing
4584
+ * rest flattened when its own type is a fixed tuple. Null for a variadic
4585
+ * position, which has no fixed native arity. */
4586
+ function signatureParameters(sig, ctx) {
4587
+ const { checker } = ctx;
4588
+ const out = [];
4589
+ for (const p of sig.getParameters()) {
4590
+ const decl = p.valueDeclaration;
4591
+ const type = checker.getTypeOfSymbol(p);
4592
+ if (decl !== undefined && ts.isParameter(decl)) {
4593
+ if (decl.dotDotDotToken !== undefined) {
4594
+ const inner = restTupleElements(type, ctx);
4595
+ if (!inner)
4596
+ return null;
4597
+ out.push(...inner);
4598
+ continue;
4599
+ }
4600
+ out.push({
4601
+ type,
4602
+ optional: decl.questionToken !== undefined || decl.initializer !== undefined,
4603
+ });
4604
+ continue;
4605
+ }
4606
+ out.push({ type, optional: (p.flags & ts.SymbolFlags.Optional) !== 0 });
4607
+ }
4608
+ return out;
4609
+ }
4610
+ /** The required-only positional parameter types of a signature (the
4611
+ * value-level `Parameters<F>` tuple), null when a position is optional
4612
+ * or variadic: such a tuple's length varies per call. */
4613
+ function signatureParameterTypes(sig, ctx) {
4614
+ const elems = signatureParameters(sig, ctx);
4615
+ if (!elems || elems.some((e) => e.optional))
4616
+ return null;
4617
+ return elems.map((e) => e.type);
4618
+ }
4619
+ /** The element types of a REST parameter's type when it is a fixed tuple:
4620
+ * a tuple of required elements (`[number, string]`, the empty `[]`), a type
4621
+ * parameter bound to one, or `Parameters<F>` over a bound function type.
4622
+ * Such a rest parameter has a compile-time arity, so its native ABI is the
4623
+ * flattened positional list (exactly the equivalent fixed signature —
4624
+ * TypeScript treats `(...a: [A, B]) => R` and `(a: A, b: B) => R` alike). */
4625
+ export function restTupleElementTypes(type, ctx) {
4626
+ return restTupleElements(type, ctx)?.map((e) => e.type) ?? null;
4627
+ }
4628
+ /** restTupleElementTypes with each position's optionality: a rest tuple
4629
+ * may end in optional positions (`[A, B?]`, `Parameters<(a: A, b?: B) =>
4630
+ * R>`), which flatten to `T | undefined` slots exactly as the function
4631
+ * type's optional parameters do. */
4632
+ function restTupleElements(type, ctx) {
4633
+ const { checker } = ctx;
4634
+ if (type.flags & ts.TypeFlags.TypeParameter) {
4635
+ const bound = ctx.resolveTypeParamTs?.(type);
4636
+ return bound && bound !== type ? restTupleElements(bound, ctx) : null;
4637
+ }
4638
+ const viaAlias = boundSignatureAlias(type, ctx);
4639
+ if (viaAlias) {
4640
+ return viaAlias.name === "Parameters" ? signatureParameters(viaAlias.sig, ctx) : null;
4641
+ }
4642
+ if (!checker.isTupleType(type))
4643
+ return null;
4644
+ const ref = type;
4645
+ const tupleShape = ref.elementFlags !== undefined
4646
+ ? ref
4647
+ : ref.getTarget();
4648
+ const args = checker.getTypeArguments(ref);
4649
+ if (args.length === 0)
4650
+ return [];
4651
+ const flags = tupleShape?.elementFlags;
4652
+ if (flags === undefined)
4653
+ return null;
4654
+ if (flags.some((f) => !(f & (ts.ElementFlags.Required | ts.ElementFlags.Optional))))
4655
+ return null;
4656
+ return args.map((t, i) => ({
4657
+ type: t,
4658
+ optional: (flags[i] & ts.ElementFlags.Optional) !== 0,
4659
+ }));
4660
+ }
4661
+ /** One tuple element's IR type under the tuple mapping's rules. */
4662
+ function mapTupleElement(t, ctx) {
4663
+ let et = (t.flags & ts.TypeFlags.Any) !== 0 ? DYN : mapType(t, ctx);
4664
+ if (et?.kind === "void" && isUnitOnlyTsType(t, ctx.resolveTypeParam))
4665
+ et = unitOnlyUnion(ctx.unions);
4666
+ return !et || et.kind === "void" ? null : et;
4667
+ }
4668
+ /** The mapped element types of a fixed-tuple rest parameter type
4669
+ * (restTupleElementTypes), null when it is not one or an element does not
4670
+ * map. */
4671
+ export function restTupleParamTypes(type, ctx) {
4672
+ const elems = restTupleElements(type, ctx);
4673
+ if (!elems)
4674
+ return null;
4675
+ const out = [];
4676
+ for (const e of elems) {
4677
+ let et = mapTupleElement(e.type, ctx);
4678
+ // An optional position's slot holds undefined when the caller omits
4679
+ // it, as an optional parameter's does (mapCallSignature).
4680
+ if (et && e.optional && et.kind !== "dyn")
4681
+ et = withUndefinedArm(et, ctx.unions);
4682
+ if (!et)
4683
+ return null;
4684
+ out.push(et);
4685
+ }
4686
+ return out;
4687
+ }
4688
+ /** `Parameters<F>` (the fixed tuple of F's parameters, interned exactly as
4689
+ * the spelled tuple maps) and `ReturnType<F>` (F's mapped result) over a
4690
+ * bound function-typed type parameter. */
4691
+ function mapBoundSignatureAlias(type, ctx) {
4692
+ const target = boundSignatureAlias(type, ctx);
4693
+ if (!target)
4694
+ return null;
4695
+ if (target.name === "ReturnType") {
4696
+ const ret = ctx.checker.getReturnTypeOfSignature(target.sig);
4697
+ return ret.flags & ts.TypeFlags.Any ? DYN : mapType(ret, ctx);
4698
+ }
4699
+ const elems = signatureParameterTypes(target.sig, ctx);
4700
+ if (!elems)
4701
+ return null;
4702
+ if (elems.length === 0)
4703
+ return arrayOf(unitOnlyUnion(ctx.unions));
4704
+ const fields = [];
4705
+ for (let i = 0; i < elems.length; i++) {
4706
+ const et = mapTupleElement(elems[i], ctx);
4707
+ if (!et)
4708
+ return null;
4709
+ fields.push({ name: String(i), type: et });
4710
+ }
4711
+ fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
4712
+ return { kind: "record", shapeId: ctx.shapes.intern(fields, true) };
4713
+ }
3934
4714
  /** `Partial<T>` / `Readonly<T>` where T is a STILL-GENERIC type parameter —
3935
4715
  * the one mapped-type spelling a monomorphized body can contain that the
3936
4716
  * checker cannot resolve for us (`keyof T` is unknown inside the body, so
@@ -3970,16 +4750,16 @@ export function underConstAssertion(n) {
3970
4750
  * panic repair): a property symbol declared by a property assignment whose
3971
4751
  * initializer is an EMPTY array literal inside a const assertion — its
3972
4752
  * type is provably `readonly []`, whatever the panicked query answered. */
3973
- function constAssertedEmptyArrayProp(p, ctx) {
3974
- const d = ctx.checker.valueDeclarationOf(p);
4753
+ function constAssertedEmptyArrayProp(p) {
4754
+ const d = p.valueDeclaration;
3975
4755
  if (d === undefined || !ts.isPropertyAssignment(d))
3976
4756
  return false;
3977
4757
  const init = d.initializer;
3978
4758
  // `a: [] as const` pins the field type by itself, wherever the literal sits.
3979
4759
  if (ts.isAsExpression(init) && isConstAssertionTypeNode(init.type)) {
3980
- return ts.isArrayLiteralExpression(init.expression) && init.expression.elements.length === 0;
4760
+ return (ts.isArrayLiteralExpression(init.expression) && init.expression.elements.nodes.length === 0);
3981
4761
  }
3982
- if (!ts.isArrayLiteralExpression(init) || init.elements.length > 0)
4762
+ if (!ts.isArrayLiteralExpression(init) || init.elements.nodes.length > 0)
3983
4763
  return false;
3984
4764
  return underConstAssertion(d);
3985
4765
  }
@@ -3988,21 +4768,22 @@ function mapGenericAwaitedAlias(type, ctx) {
3988
4768
  if (!resolveTypeParam)
3989
4769
  return null;
3990
4770
  const alias = type.getAliasSymbol();
3991
- if (!alias || alias.name !== "Awaited")
4771
+ if (!alias || ts.symbolName(alias) !== "Awaited")
3992
4772
  return null;
3993
4773
  const aliasArgs = type.getAliasTypeArguments();
3994
4774
  const arg = aliasArgs[0];
3995
4775
  if (aliasArgs.length !== 1 || !arg)
3996
4776
  return null;
3997
- if (!(arg.flags & ts.TypeFlags.TypeParameter))
4777
+ // `Awaited<ReturnType<F>>` (an async wrapper's settled result) resolves
4778
+ // through F's bound signature like a bare type parameter.
4779
+ const viaSignature = arg.flags & ts.TypeFlags.TypeParameter ? null : boundSignatureAlias(arg, ctx);
4780
+ if (!(arg.flags & ts.TypeFlags.TypeParameter) && viaSignature?.name !== "ReturnType")
3998
4781
  return null;
3999
4782
  // Provenance: the STANDARD LIBRARY's alias, not a user's shadowing one.
4000
- const isLibAlias = ctx.checker
4001
- .declarationsOf(alias)
4002
- .some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()));
4783
+ const isLibAlias = alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
4003
4784
  if (!isLibAlias)
4004
4785
  return null;
4005
- const bound = resolveTypeParam(arg);
4786
+ const bound = viaSignature ? mapBoundSignatureAlias(arg, ctx) : resolveTypeParam(arg);
4006
4787
  if (!bound)
4007
4788
  return null;
4008
4789
  let r = bound;
@@ -4031,14 +4812,19 @@ function mapGenericIndexedAccess(type, ctx) {
4031
4812
  if (obj === undefined || !(obj.flags & ts.TypeFlags.TypeParameter))
4032
4813
  return null;
4033
4814
  const bound = resolveTypeParam(obj);
4815
+ const idx = type.getIndexType();
4816
+ if (idx === undefined)
4817
+ return null;
4818
+ // `T[keyof T]` over a T bound to an unknown-valued record view
4819
+ // (`Record<string, unknown>` maps to the checked-dynamic value, see
4820
+ // mapRecordType): every member reads as unknown.
4821
+ if (bound?.kind === "dyn" && idx.isIndexType() && idx.getTarget() === obj)
4822
+ return DYN;
4034
4823
  if (!bound || bound.kind !== "record")
4035
4824
  return null;
4036
4825
  const shape = shapes.get(bound.shapeId);
4037
4826
  if (!shape || shape.tuple)
4038
4827
  return null;
4039
- const idx = type.getIndexType();
4040
- if (idx === undefined)
4041
- return null;
4042
4828
  let covered = null;
4043
4829
  if (idx.isStringLiteralType()) {
4044
4830
  const f = shape.fields.find((x) => x.name === idx.value);
@@ -4057,14 +4843,414 @@ function mapGenericIndexedAccess(type, ctx) {
4057
4843
  if (!covered || covered.length === 0)
4058
4844
  return null;
4059
4845
  const first = covered[0];
4060
- return covered.every((t) => typeEquals(t, first)) ? first : null;
4846
+ if (covered.every((t) => typeEquals(t, first)))
4847
+ return first;
4848
+ // Only the `keyof T` index itself covers every field at once; a key
4849
+ // parameter bound to string keeps its literal-key resolution below.
4850
+ if (!(idx.isIndexType() && idx.getTarget() === obj))
4851
+ return null;
4852
+ // Fields of different scalar types (`Object.entries` over a bound record
4853
+ // reads `T[keyof T]`): any one of them, the union of their types.
4854
+ const arms = [];
4855
+ for (const t of covered) {
4856
+ const parts = t.kind === "union" ? (ctx.unions.get(t.unionId)?.arms ?? null) : [t];
4857
+ if (!parts)
4858
+ return null;
4859
+ for (const part of parts) {
4860
+ if (part.kind !== "f64" &&
4861
+ part.kind !== "string" &&
4862
+ part.kind !== "bool" &&
4863
+ part.kind !== "undefinedT" &&
4864
+ part.kind !== "nullT")
4865
+ return null;
4866
+ if (!arms.some((a) => typeEquals(a, part)))
4867
+ arms.push(part);
4868
+ }
4869
+ }
4870
+ if (arms.length === 1)
4871
+ return arms[0];
4872
+ arms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
4873
+ return { kind: "union", unionId: ctx.unions.intern(arms) };
4874
+ }
4875
+ /** `keyof T extends never ? A : B` over a bound record T (the lib's
4876
+ * Object.entries element spelling): decided by whether the binding has any
4877
+ * key. */
4878
+ function mapBoundKeyofNeverConditional(type, ctx) {
4879
+ const { resolveTypeParam, shapes } = ctx;
4880
+ if (!resolveTypeParam || !type.isConditionalType())
4881
+ return null;
4882
+ const check = type.getCheckType();
4883
+ const ext = type.getExtendsType();
4884
+ if (!check || !ext || !(ext.flags & ts.TypeFlags.Never) || !check.isIndexType())
4885
+ return null;
4886
+ const target = check.getTarget();
4887
+ if (!target || !(target.flags & ts.TypeFlags.TypeParameter))
4888
+ return null;
4889
+ const bound = resolveTypeParam(target);
4890
+ // A T bound to the checked-dynamic value (`Record<string, unknown>`, an
4891
+ // unknown-valued record view) has no static key set to decide the
4892
+ // branch, but both branches of the lib's `keyof T extends never ?
4893
+ // unknown : T[keyof T]` read as unknown there: one answer either way.
4894
+ if (bound?.kind === "dyn") {
4895
+ const whenEmpty = type.getTrueType();
4896
+ const otherwise = type.getFalseType();
4897
+ const a = whenEmpty ? mapType(whenEmpty, ctx) : null;
4898
+ const b = otherwise ? mapType(otherwise, ctx) : null;
4899
+ return a && b && typeEquals(a, b) ? a : null;
4900
+ }
4901
+ if (bound?.kind !== "record")
4902
+ return null;
4903
+ const shape = shapes.get(bound.shapeId);
4904
+ if (!shape || shape.tuple)
4905
+ return null;
4906
+ const hasKeys = shape.fields.length > 0 || shape.indexValue !== undefined;
4907
+ const branch = hasKeys ? type.getFalseType() : type.getTrueType();
4908
+ return branch ? mapType(branch, ctx) : null;
4909
+ }
4910
+ /** A mapped type over a type parameter of the instance being lowered (`{
4911
+ * [K in keyof S]: S[K] }`, `{ [K in keyof S]: Infer<S[K]> }`): the checker
4912
+ * keeps it symbolic inside the generic body, but the instance binds `S`,
4913
+ * so each property of the bound type maps through the template evaluated
4914
+ * with `K` set to that property's key. Optionality follows the `?`
4915
+ * modifier, or the bound property's own for a homomorphic mapping. Null
4916
+ * when the shape is anything else or a template form does not evaluate. */
4917
+ function mapBoundMappedType(widened, ctx) {
4918
+ const { checker, resolveTypeParamTs, shapes, unions } = ctx;
4919
+ if (!resolveTypeParamTs || !isMappedShape(widened))
4920
+ return null;
4921
+ const symbol = widened.getSymbol();
4922
+ const node = symbol
4923
+ ? symbol.declarations.find((d) => ts.isMappedTypeNode(d))
4924
+ : undefined;
4925
+ const constraint = node?.typeParameter.constraint;
4926
+ if (!node?.type ||
4927
+ !constraint ||
4928
+ !ts.isTypeOperatorNode(constraint) ||
4929
+ constraint.operator !== ts.SyntaxKind.KeyOfKeyword)
4930
+ return null;
4931
+ const source = checker.getTypeFromTypeNode(constraint.type);
4932
+ if (!(source.flags & ts.TypeFlags.TypeParameter))
4933
+ return null;
4934
+ const bound = resolveTypeParamTs(source);
4935
+ const key = checker.getSymbolAtLocation(node.typeParameter.name);
4936
+ if (!bound || !key)
4937
+ return null;
4938
+ const template = checker.getTypeFromTypeNode(node.type);
4939
+ const modifier = node.questionToken?.kind;
4940
+ const fields = [];
4941
+ const order = [];
4942
+ for (const property of checker.getPropertiesOfType(bound)) {
4943
+ const name = ts.symbolName(property);
4944
+ const evaluated = evalMappedTemplate(template, new Map([[key, name]]), new Map(), ctx);
4945
+ let type = evaluated ? mapType(evaluated, ctx) : null;
4946
+ if (!type)
4947
+ return null;
4948
+ const optional = modifier === ts.SyntaxKind.MinusToken
4949
+ ? false
4950
+ : modifier !== undefined || (property.flags & ts.SymbolFlags.Optional) !== 0;
4951
+ if (optional) {
4952
+ const armed = withUndefinedArm(type, unions);
4953
+ if (!armed)
4954
+ return null;
4955
+ type = armed;
4956
+ }
4957
+ fields.push({ name, type });
4958
+ order.push(name);
4959
+ }
4960
+ fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
4961
+ return { kind: "record", shapeId: shapes.intern(fields, false, undefined, order) };
4962
+ }
4963
+ /** The checker type a mapped type's template stands for at one key:
4964
+ * `keys` binds the mapped type parameter to a property name, `aliases`
4965
+ * binds type-alias and `infer` parameters met on the way. Handles type
4966
+ * parameters (through the instance's bindings), indexed accesses
4967
+ * (`S[K]`, `S[K]["_output"]`) and conditional types whose `extends` side
4968
+ * is a reference to the same generic type as the checked type
4969
+ * (`S extends Schema<infer T> ? T : never`); answers the type itself
4970
+ * when it mentions none of the bound parameters, null otherwise. */
4971
+ function evalMappedTemplate(type, keys, aliases, ctx) {
4972
+ const { checker, resolveTypeParamTs } = ctx;
4973
+ if (type.flags & ts.TypeFlags.TypeParameter) {
4974
+ const symbol = type.getSymbol();
4975
+ if (symbol && keys.has(symbol))
4976
+ return null;
4977
+ if (symbol && aliases.has(symbol))
4978
+ return aliases.get(symbol);
4979
+ return resolveTypeParamTs?.(type) ?? null;
4980
+ }
4981
+ if (type.isIndexedAccessType()) {
4982
+ const object = type.getObjectType();
4983
+ const index = type.getIndexType();
4984
+ if (!object || !index)
4985
+ return null;
4986
+ const receiver = evalMappedTemplate(object, keys, aliases, ctx);
4987
+ const indexSymbol = index.flags & ts.TypeFlags.TypeParameter ? index.getSymbol() : undefined;
4988
+ const name = indexSymbol && keys.has(indexSymbol)
4989
+ ? keys.get(indexSymbol)
4990
+ : index.isStringLiteralType()
4991
+ ? index.value
4992
+ : index.isNumberLiteralType()
4993
+ ? String(index.value)
4994
+ : null;
4995
+ if (!receiver || name === null)
4996
+ return null;
4997
+ const property = checker.getPropertyOfType(receiver, name);
4998
+ return property ? checker.getTypeOfSymbol(property) : null;
4999
+ }
5000
+ if (type.isConditionalType()) {
5001
+ // A conditional reached through an alias (`Infer<S[K]>`) checks the
5002
+ // alias's own parameters: bind them to the evaluated arguments.
5003
+ let scope = aliases;
5004
+ const alias = type.getAliasSymbol();
5005
+ const aliasArgs = type.getAliasTypeArguments();
5006
+ const aliasDecl = alias
5007
+ ? alias.declarations.find((d) => ts.isTypeAliasDeclaration(d))
5008
+ : undefined;
5009
+ if (aliasDecl?.typeParameters?.nodes &&
5010
+ aliasArgs.length === aliasDecl.typeParameters.nodes.length) {
5011
+ scope = new Map(aliases);
5012
+ for (let i = 0; i < aliasArgs.length; i++) {
5013
+ const param = checker.getSymbolAtLocation(aliasDecl.typeParameters.nodes[i].name);
5014
+ const arg = evalMappedTemplate(aliasArgs[i], keys, aliases, ctx);
5015
+ if (!param || !arg)
5016
+ return null;
5017
+ scope.set(param, arg);
5018
+ }
5019
+ }
5020
+ const checkType = type.getCheckType();
5021
+ const extendsType = type.getExtendsType();
5022
+ if (!checkType || !extendsType)
5023
+ return null;
5024
+ const checked = evalMappedTemplate(checkType, keys, scope, ctx);
5025
+ if (!checked)
5026
+ return null;
5027
+ const inferred = matchInferReference(checked, extendsType, ctx);
5028
+ if (inferred === undefined)
5029
+ return null;
5030
+ const branch = inferred ? type.getTrueType() : type.getFalseType();
5031
+ const branchScope = inferred ? new Map([...scope, ...inferred]) : scope;
5032
+ return evalMappedTemplate(branch, keys, branchScope, ctx);
5033
+ }
5034
+ return mentionsMappedParams(type, keys, aliases) ? null : type;
5035
+ }
5036
+ /** `checked extends G<..., infer T, ...>`: the infer bindings when
5037
+ * `checked` is a reference to the same generic `G` (its arguments bind the
5038
+ * infer positions; other positions must be the same types), false when it
5039
+ * is a reference to another type or a primitive, undefined when the match
5040
+ * cannot be decided this way. */
5041
+ function matchInferReference(checked, extendsType, ctx) {
5042
+ const { checker } = ctx;
5043
+ const target = (t) => t.isTypeReference?.() ? t.getTarget?.() : undefined;
5044
+ const wantTarget = target(extendsType) ?? extendsType.getAliasSymbol();
5045
+ if (!wantTarget)
5046
+ return matchInferSignature(checked, extendsType, ctx);
5047
+ const gotTarget = target(checked) ?? checked.getAliasSymbol();
5048
+ if (!gotTarget)
5049
+ return checked.flags & ts.TypeFlags.Object
5050
+ ? matchInferThenable(checked, extendsType, ctx)
5051
+ : false;
5052
+ if (gotTarget !== wantTarget)
5053
+ return matchInferThenable(checked, extendsType, ctx);
5054
+ const wantArgs = target(extendsType)
5055
+ ? checker.getTypeArguments(extendsType)
5056
+ : extendsType.getAliasTypeArguments();
5057
+ const gotArgs = target(checked)
5058
+ ? checker.getTypeArguments(checked)
5059
+ : checked.getAliasTypeArguments();
5060
+ if (wantArgs.length !== gotArgs.length)
5061
+ return undefined;
5062
+ const inferred = new Map();
5063
+ for (let i = 0; i < wantArgs.length; i++) {
5064
+ const want = wantArgs[i];
5065
+ const symbol = want.flags & ts.TypeFlags.TypeParameter ? want.getSymbol() : undefined;
5066
+ const isInfer = symbol
5067
+ ? symbol.declarations.some((d) => d.parent !== undefined && ts.isInferTypeNode(d.parent))
5068
+ : false;
5069
+ if (isInfer && symbol)
5070
+ inferred.set(symbol, gotArgs[i]);
5071
+ else if (want !== gotArgs[i])
5072
+ return undefined;
5073
+ }
5074
+ return inferred;
5075
+ }
5076
+ /** The type parameter an `infer X` declares, when `t` is one. */
5077
+ function inferSymbolOf(t, _ctx) {
5078
+ if (!(t.flags & ts.TypeFlags.TypeParameter))
5079
+ return undefined;
5080
+ const symbol = t.getSymbol();
5081
+ return symbol &&
5082
+ symbol.declarations.some((d) => d.parent !== undefined && ts.isInferTypeNode(d.parent))
5083
+ ? symbol
5084
+ : undefined;
5085
+ }
5086
+ /** `checked extends (...args: any) => infer R` — the shape of the standard
5087
+ * library's ReturnType, over a concrete function type: R binds to its
5088
+ * result. Pattern parameters must be `any` or `any[]`, and a pattern rest
5089
+ * `any` or `any[]`; anything else stays undecided. The match follows
5090
+ * TypeScript's assignability: a primitive never matches a function type,
5091
+ * a function that needs more arguments than a pattern without a rest
5092
+ * passes never matches, and a positional `any[]` parameter needs the
5093
+ * function's parameter there to accept an array. */
5094
+ function matchInferSignature(checked, extendsType, ctx) {
5095
+ const { checker } = ctx;
5096
+ const wantSigs = checker.getCallSignatures(extendsType);
5097
+ const want = wantSigs[0];
5098
+ if (wantSigs.length !== 1 || !want || want.getTypeParameters().length > 0)
5099
+ return undefined;
5100
+ const wantShape = signatureShape(want, ctx);
5101
+ if (wantShape === undefined)
5102
+ return undefined;
5103
+ const isAny = (t) => (t.flags & ts.TypeFlags.Any) !== 0;
5104
+ const isAnyArray = (t) => checker.isArrayType(t) && isAny(checker.getTypeArguments(t)[0]);
5105
+ if (!wantShape.params.every((p) => isAny(p.type) || isAnyArray(p.type)))
5106
+ return undefined;
5107
+ if (wantShape.rest !== null && !isAny(wantShape.rest))
5108
+ return undefined;
5109
+ if (!(checked.flags & ts.TypeFlags.Object))
5110
+ return false;
5111
+ const gotSigs = checker.getCallSignatures(checked);
5112
+ const got = gotSigs[0];
5113
+ if (gotSigs.length !== 1 || !got || got.getTypeParameters().length > 0)
5114
+ return undefined;
5115
+ const gotShape = signatureShape(got, ctx);
5116
+ if (gotShape !== undefined) {
5117
+ // `(a: any) => infer R` rejects `(a: string, b: string) => R` and
5118
+ // `(...args: [string, number]) => R`: they need more arguments.
5119
+ if (wantShape.rest === null && requiredArguments(gotShape) > wantShape.params.length)
5120
+ return false;
5121
+ for (let i = 0; i < wantShape.params.length; i++) {
5122
+ if (!isAnyArray(wantShape.params[i].type))
5123
+ continue;
5124
+ const param = gotShape.params[i]?.type ?? gotShape.rest;
5125
+ if (param === undefined || param === null)
5126
+ continue;
5127
+ const accepts = acceptsArray(param, ctx);
5128
+ if (accepts !== true)
5129
+ return accepts;
5130
+ }
5131
+ }
5132
+ else if (wantShape.params.some((p) => isAnyArray(p.type))) {
5133
+ return undefined;
5134
+ }
5135
+ const wantRet = checker.getReturnTypeOfSignature(want);
5136
+ const infer = inferSymbolOf(wantRet, ctx);
5137
+ if (infer)
5138
+ return new Map([[infer, checker.getReturnTypeOfSignature(got)]]);
5139
+ return wantRet.flags & ts.TypeFlags.Any ? new Map() : undefined;
5140
+ }
5141
+ /** A signature's parameters as a call sees them: the positional ones, with
5142
+ * a fixed-tuple rest (`...args: [A, B?]`) flattened into positions, and the
5143
+ * element type of an array rest (`any` for `...args: any`). Undefined when
5144
+ * a parameter has no declaration, or the rest is a variadic tuple or
5145
+ * another type. */
5146
+ function signatureShape(sig, ctx) {
5147
+ const { checker } = ctx;
5148
+ const params = [];
5149
+ for (const p of sig.getParameters()) {
5150
+ const decl = p.valueDeclaration;
5151
+ if (decl === undefined || !ts.isParameter(decl))
5152
+ return undefined;
5153
+ const type = checker.getTypeOfSymbol(p);
5154
+ if (decl.dotDotDotToken === undefined) {
5155
+ params.push({
5156
+ type,
5157
+ optional: decl.questionToken !== undefined || decl.initializer !== undefined,
5158
+ });
5159
+ continue;
5160
+ }
5161
+ if (type.flags & ts.TypeFlags.Any)
5162
+ return { params, rest: type };
5163
+ if (checker.isArrayType(type))
5164
+ return { params, rest: checker.getTypeArguments(type)[0] };
5165
+ const elems = restTupleElements(type, ctx);
5166
+ if (!elems)
5167
+ return undefined;
5168
+ for (const e of elems)
5169
+ params.push({ type: e.type, optional: e.optional });
5170
+ return { params, rest: null };
5171
+ }
5172
+ return { params, rest: null };
5173
+ }
5174
+ /** The fewest arguments a call must pass: up to the last required position. */
5175
+ function requiredArguments(shape) {
5176
+ let required = 0;
5177
+ shape.params.forEach((p, i) => {
5178
+ if (!p.optional)
5179
+ required = i + 1;
5180
+ });
5181
+ return required;
5182
+ }
5183
+ /** Whether a parameter of this type accepts an `any[]` argument: true for
5184
+ * `any`, `unknown` and array types, false for primitives, undefined
5185
+ * otherwise. */
5186
+ function acceptsArray(t, ctx) {
5187
+ if (t.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown))
5188
+ return true;
5189
+ if (ctx.checker.isArrayType(t))
5190
+ return true;
5191
+ const primitive = ts.TypeFlags.StringLike |
5192
+ ts.TypeFlags.NumberLike |
5193
+ ts.TypeFlags.BooleanLike |
5194
+ ts.TypeFlags.BigIntLike |
5195
+ ts.TypeFlags.ESSymbolLike |
5196
+ ts.TypeFlags.Undefined |
5197
+ ts.TypeFlags.Null |
5198
+ ts.TypeFlags.Void;
5199
+ return t.flags & primitive ? false : undefined;
5200
+ }
5201
+ /** `checked extends PromiseLike<infer U>` (or `Promise<infer U>`) over the
5202
+ * standard library's Promise: U binds to the settled type. An object with
5203
+ * no `then` member is no thenable. Everything else stays undecided. */
5204
+ function matchInferThenable(checked, extendsType, ctx) {
5205
+ const { checker } = ctx;
5206
+ const stdlibNamed = (t, names) => {
5207
+ const symbol = t.getSymbol();
5208
+ return (symbol !== undefined &&
5209
+ names.includes(ts.symbolName(symbol)) &&
5210
+ symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d))));
5211
+ };
5212
+ if (!stdlibNamed(extendsType, ["PromiseLike", "Promise"]))
5213
+ return undefined;
5214
+ const wantArgs = checker.getTypeArguments(extendsType);
5215
+ const infer = wantArgs.length === 1 ? inferSymbolOf(wantArgs[0], ctx) : undefined;
5216
+ if (!infer)
5217
+ return undefined;
5218
+ if (stdlibNamed(checked, ["Promise", "PromiseLike"])) {
5219
+ const gotArgs = checker.getTypeArguments(checked);
5220
+ return gotArgs.length === 1 ? new Map([[infer, gotArgs[0]]]) : undefined;
5221
+ }
5222
+ return checker.getPropertyOfType(checked, "then") === undefined ? false : undefined;
5223
+ }
5224
+ /** The type mentions a mapped key or bound alias parameter (a template
5225
+ * shape evalMappedTemplate does not reduce). */
5226
+ function mentionsMappedParams(type, keys, aliases) {
5227
+ if (type.flags & ts.TypeFlags.TypeParameter) {
5228
+ const symbol = type.getSymbol();
5229
+ return symbol !== undefined && (keys.has(symbol) || aliases.has(symbol));
5230
+ }
5231
+ if (type.isUnionType() || type.isIntersectionType())
5232
+ return ts.constituentTypes(type).some((part) => mentionsMappedParams(part, keys, aliases));
5233
+ return false;
5234
+ }
5235
+ function readonlyClassType(type, ctx) {
5236
+ const alias = type.getAliasSymbol();
5237
+ if (alias === undefined || ts.symbolName(alias) !== "Readonly")
5238
+ return null;
5239
+ const args = type.getAliasTypeArguments();
5240
+ if (args.length !== 1 || !args[0])
5241
+ return null;
5242
+ const isLibAlias = alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
5243
+ if (!isLibAlias)
5244
+ return null;
5245
+ const mapped = mapType(args[0], ctx);
5246
+ return mapped !== null && isDynTypedRefType(mapped) ? mapped : null;
4061
5247
  }
4062
5248
  function mapGenericUtilityAlias(widened, ctx) {
4063
5249
  const { resolveTypeParam, shapes, unions } = ctx;
4064
5250
  if (!resolveTypeParam)
4065
5251
  return null;
4066
5252
  const alias = widened.getAliasSymbol();
4067
- if (!alias || (alias.name !== "Partial" && alias.name !== "Readonly"))
5253
+ if (!alias || (ts.symbolName(alias) !== "Partial" && ts.symbolName(alias) !== "Readonly"))
4068
5254
  return null;
4069
5255
  const aliasArgs = widened.getAliasTypeArguments();
4070
5256
  const arg = aliasArgs[0];
@@ -4073,15 +5259,13 @@ function mapGenericUtilityAlias(widened, ctx) {
4073
5259
  if (!(arg.flags & ts.TypeFlags.TypeParameter))
4074
5260
  return null;
4075
5261
  // Provenance: the STANDARD LIBRARY's alias, not a user's shadowing one.
4076
- const isLibAlias = ctx.checker
4077
- .declarationsOf(alias)
4078
- .some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()));
5262
+ const isLibAlias = alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
4079
5263
  if (!isLibAlias)
4080
5264
  return null;
4081
5265
  const bound = resolveTypeParam(arg);
4082
5266
  if (!bound || bound.kind !== "record")
4083
5267
  return null;
4084
- if (alias.name === "Readonly")
5268
+ if (ts.symbolName(alias) === "Readonly")
4085
5269
  return bound;
4086
5270
  const shape = shapes.get(bound.shapeId);
4087
5271
  if (!shape)
@@ -4191,7 +5375,20 @@ export function isUnitOnlyTsType(t, resolveTypeParam) {
4191
5375
  const UNIT = ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Null;
4192
5376
  const parts = t.isUnionType() ? ts.constituentTypes(t) : [t];
4193
5377
  return parts.every((p) => (p.flags & UNIT) !== 0 ||
4194
- ((p.flags & ts.TypeFlags.TypeParameter) !== 0 && resolveTypeParam?.(p)?.kind === "void"));
5378
+ ((p.flags & ts.TypeFlags.TypeParameter) !== 0 && resolveTypeParam?.(p)?.kind === "void") ||
5379
+ boundVoidReturnType(p, resolveTypeParam));
5380
+ }
5381
+ /** `ReturnType<F>` over a type parameter bound to a void-returning
5382
+ * function (a variadic wrapper's result slot): a unit-only value. */
5383
+ function boundVoidReturnType(p, resolveTypeParam) {
5384
+ if (!resolveTypeParam || ts.symbolNameOf(p.getAliasSymbol()) !== "ReturnType")
5385
+ return false;
5386
+ const args = p.getAliasTypeArguments();
5387
+ const arg = args[0];
5388
+ if (args.length !== 1 || !arg || !(arg.flags & ts.TypeFlags.TypeParameter))
5389
+ return false;
5390
+ const bound = resolveTypeParam(arg);
5391
+ return bound?.kind === "func" && bound.ret.kind === "void";
4195
5392
  }
4196
5393
  /** IR-level `t | undefined`, canonicalized and fenced exactly like the
4197
5394
  * ts-union branch of mapType (typeKey-sorted arms, deduplicated;
@@ -4274,8 +5471,8 @@ function mapHybridCallableIntersection(widened, ctx) {
4274
5471
  const pt = mapType(checker.getTypeOfSymbol(p), ctx);
4275
5472
  if (!pt || pt.kind === "void")
4276
5473
  return null;
4277
- fields.push({ name: p.name, type: pt });
4278
- declaredOrder.push(p.name);
5474
+ fields.push({ name: ts.symbolName(p), type: pt });
5475
+ declaredOrder.push(ts.symbolName(p));
4279
5476
  }
4280
5477
  if (fields.length === 1)
4281
5478
  return null; // no properties — it is just F
@@ -4318,12 +5515,13 @@ function mapErrorMetadataIntersection(type, ctx) {
4318
5515
  "URIError",
4319
5516
  "AggregateError",
4320
5517
  "SuppressedError",
4321
- ].includes(symbol.name) &&
4322
- ctx.checker.declarationsOf(symbol).some((decl) => ctx.isStdlibFile(decl.getSourceFile())));
5518
+ ].includes(ts.symbolName(symbol)) &&
5519
+ symbol.declarations.some((decl) => ctx.isStdlibFile(ts.getSourceFileOfNode(decl))));
4323
5520
  });
4324
5521
  if (!hasError)
4325
5522
  return null;
4326
5523
  let error = null;
5524
+ const extra = [];
4327
5525
  for (const part of parts) {
4328
5526
  const mapped = mapType(part, ctx);
4329
5527
  if (mapped?.kind === "object" && RUNTIME_ERROR_CLASSES.has(mapped.className)) {
@@ -4337,19 +5535,45 @@ function mapErrorMetadataIntersection(type, ctx) {
4337
5535
  ctx.checker.getIndexInfosOfType(part).length)
4338
5536
  return null;
4339
5537
  for (const property of ctx.checker.getPropertiesOfType(part)) {
4340
- const expected = property.name === "errno"
5538
+ const expected = ts.symbolName(property) === "errno"
4341
5539
  ? "f64"
4342
- : ["code", "syscall", "path", "dest"].includes(property.name)
5540
+ : ["code", "syscall", "path", "dest"].includes(ts.symbolName(property))
4343
5541
  ? "string"
4344
5542
  : null;
4345
- if (!expected || !(property.flags & ts.SymbolFlags.Optional))
4346
- return null;
5543
+ if (!expected) {
5544
+ extra.push(property);
5545
+ continue;
5546
+ }
4347
5547
  const field = mapType(ctx.checker.getTypeOfSymbol(property), ctx);
4348
5548
  const arms = field?.kind === "union" ? ctx.unions.get(field.unionId)?.arms : field ? [field] : [];
4349
5549
  if (!arms?.length || !arms.every((arm) => arm.kind === expected || arm.kind === "undefinedT"))
4350
5550
  return null;
5551
+ // A required member must still admit the absent value the slot reads.
5552
+ if (!(property.flags & ts.SymbolFlags.Optional) &&
5553
+ !arms.some((arm) => arm.kind === "undefinedT"))
5554
+ return null;
4351
5555
  }
4352
5556
  }
5557
+ if (!error)
5558
+ return null;
5559
+ // Members beyond Error's own and the system-error metadata (`Error & {
5560
+ // status: number }`, Object.assign's result) are own properties of the
5561
+ // error's checked-dynamic node: each must map to a type a checked read
5562
+ // can produce. Error's own string members keep their slots.
5563
+ for (const property of extra) {
5564
+ const field = mapType(ctx.checker.getTypeOfSymbol(property), ctx);
5565
+ if (!field || field.kind === "void")
5566
+ return null;
5567
+ if (ts.symbolName(property) === "message" || ts.symbolName(property) === "name") {
5568
+ if (field.kind !== "string")
5569
+ return null;
5570
+ continue;
5571
+ }
5572
+ if (ts.symbolName(property) === "stack" || ts.symbolName(property) === "cause")
5573
+ return null;
5574
+ if (!canDynCheckTo(field, (id) => ctx.shapes.get(id), (id) => ctx.unions.get(id)))
5575
+ return null;
5576
+ }
4353
5577
  return error;
4354
5578
  }
4355
5579
  /** A conventional primitive brand has one runtime-carrying primitive part
@@ -4456,13 +5680,13 @@ function immutableSourceType(type, ctx) {
4456
5680
  return null;
4457
5681
  const { checker } = ctx;
4458
5682
  const symbol = type.getSymbol();
4459
- const decl = symbol ? checker.declarationsOf(symbol)[0] : undefined;
4460
- if (decl === undefined || !CONTRACT_TYPES_FILE.test(decl.getSourceFile().fileName))
5683
+ const decl = symbol ? symbol.declarations[0] : undefined;
5684
+ if (decl === undefined || !CONTRACT_TYPES_FILE.test(ts.getSourceFileOfNode(decl).fileName))
4461
5685
  return null;
4462
5686
  const props = checker.getPropertiesOfType(type);
4463
5687
  const seen = new Set();
4464
5688
  for (const prop of props) {
4465
- const owner = checker.declarationsOf(prop)[0]?.parent;
5689
+ const owner = prop.declarations[0]?.parent;
4466
5690
  if (owner === undefined || seen.has(owner))
4467
5691
  continue;
4468
5692
  seen.add(owner);
@@ -4471,7 +5695,7 @@ function immutableSourceType(type, ctx) {
4471
5695
  source = checker.getTypeFromTypeNode(owner);
4472
5696
  else if ((ts.isClassDeclaration(owner) || ts.isInterfaceDeclaration(owner)) &&
4473
5697
  owner.name !== undefined &&
4474
- (owner.typeParameters?.length ?? 0) === 0) {
5698
+ (owner.typeParameters?.nodes.length ?? 0) === 0) {
4475
5699
  const ownerSymbol = checker.getSymbolAtLocation(owner.name);
4476
5700
  if (ownerSymbol)
4477
5701
  source = checker.getDeclaredTypeOfSymbol(ownerSymbol);
@@ -4489,6 +5713,14 @@ function isMappedShape(t) {
4489
5713
  return ((t.flags & ts.TypeFlags.Object) !== 0 &&
4490
5714
  (t.objectFlags & ts.ObjectFlags.Mapped) !== 0);
4491
5715
  }
5716
+ /** A declaration file an installed package ships (its own or an @types
5717
+ * twin), outside the standard library and @types/node: the type surface
5718
+ * of a package the program does not compile. Its pure type shapes —
5719
+ * interfaces, aliases, type literals — describe data a program can build
5720
+ * itself (`import type` from a types-only package such as type-fest). */
5721
+ function packageTypeFile(sf, ctx) {
5722
+ return (sf.isDeclarationFile && /[\\/]node_modules[\\/]/.test(sf.fileName) && !ctx.isStdlibFile(sf));
5723
+ }
4492
5724
  /** The record path's provenance fence. Declared shapes (object literals,
4493
5725
  * interfaces, type literals) must come from user code or an explicitly
4494
5726
  * mapped external type surface, never an arbitrary .d.ts — the empty
@@ -4514,20 +5746,19 @@ function recordProvenanceOk(t, ctx) {
4514
5746
  if (isMappedShape(t))
4515
5747
  return true;
4516
5748
  const tSym = t.getSymbol();
4517
- const decls = tSym ? checker.declarationsOf(tSym) : undefined;
5749
+ const decls = tSym ? tSym.declarations : undefined;
4518
5750
  if (!decls || decls.length === 0) {
4519
5751
  // Inferred destructuring parameters can have a synthesized anonymous
4520
5752
  // shape with no declaration or member symbols to trace to a source.
4521
5753
  return checker
4522
5754
  .getPropertiesOfType(t)
4523
- .every((property) => checker
4524
- .declarationsOf(property)
4525
- .every((decl) => !decl.getSourceFile().isDeclarationFile ||
4526
- ctx.isExternalTypeFile(decl.getSourceFile())));
5755
+ .every((property) => property.declarations.every((decl) => !ts.getSourceFileOfNode(decl).isDeclarationFile ||
5756
+ ctx.isExternalTypeFile(ts.getSourceFileOfNode(decl)) ||
5757
+ packageTypeFile(ts.getSourceFileOfNode(decl), ctx)));
4527
5758
  }
4528
5759
  return !decls.some((d) => {
4529
- const sf = d.getSourceFile();
4530
- return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf);
5760
+ const sf = ts.getSourceFileOfNode(d);
5761
+ return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf) && !packageTypeFile(sf, ctx);
4531
5762
  });
4532
5763
  }
4533
5764
  /** A GENERIC-callable member type (`m<T>(x: T): T` / `f: <T>(x: T) => T` in
@@ -4549,6 +5780,213 @@ export function isGenericCallableMemberType(t, checker) {
4549
5780
  checker.getPropertiesOfType(t).length === 0 &&
4550
5781
  checker.getIndexInfosOfType(t).length === 0);
4551
5782
  }
5783
+ /** Result containers an erased async function or generator must keep:
5784
+ * their contents are erased instead (`Promise<T>` maps as
5785
+ * `Promise<unknown>`). */
5786
+ const ERASURE_KEPT_CONTAINERS = new Set(["Promise", "Generator", "AsyncGenerator"]);
5787
+ /** The type mentions a type parameter that the active erasure binds to
5788
+ * `unknown` (erasedGenericMemberType, erased bodies). */
5789
+ function mentionsErasedTypeParam(type, ctx, depth) {
5790
+ if (depth > 8)
5791
+ return false;
5792
+ const { checker } = ctx;
5793
+ if (type.flags & ts.TypeFlags.TypeParameter)
5794
+ return ctx.resolveTypeParam?.(type)?.kind === "dyn";
5795
+ if (type.flags &
5796
+ (ts.TypeFlags.IndexedAccess | ts.TypeFlags.Conditional | ts.TypeFlags.Substitution))
5797
+ return true;
5798
+ if (type.isUnionType() || type.isIntersectionType())
5799
+ return ts.constituentTypes(type).some((part) => mentionsErasedTypeParam(part, ctx, depth + 1));
5800
+ if ((type.flags & ts.TypeFlags.Object) === 0)
5801
+ return false;
5802
+ if (type.isTypeReference() &&
5803
+ checker
5804
+ .getTypeArguments(type)
5805
+ .some((arg) => mentionsErasedTypeParam(arg, ctx, depth + 1)))
5806
+ return true;
5807
+ for (const sig of checker.getCallSignatures(type)) {
5808
+ if (mentionsErasedTypeParam(checker.getReturnTypeOfSignature(sig), ctx, depth + 1))
5809
+ return true;
5810
+ for (const param of sig.getParameters())
5811
+ if (mentionsErasedTypeParam(checker.getTypeOfSymbol(param), ctx, depth + 1))
5812
+ return true;
5813
+ }
5814
+ const symbol = type.getSymbol();
5815
+ const anonymous = symbol !== undefined &&
5816
+ (symbol.flags & (ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.ObjectLiteral)) !== 0;
5817
+ if (anonymous)
5818
+ for (const property of checker.getPropertiesOfType(type))
5819
+ if (mentionsErasedTypeParam(checker.getTypeOfSymbol(property), ctx, depth + 1))
5820
+ return true;
5821
+ return false;
5822
+ }
5823
+ /** A generic callable member's runtime type: its one call signature with
5824
+ * every own type parameter bound to `unknown`, the erased instance a stored
5825
+ * or escaping definition carries (JavaScript erases type parameters the
5826
+ * same way). Undefined when the member has overloads or the erased
5827
+ * signature does not map: the member then stays out of the shape, and only
5828
+ * calls on a provable definition compile. */
5829
+ export function erasedGenericMemberType(t, ctx) {
5830
+ const sigs = ctx.checker.getCallSignatures(t);
5831
+ if (sigs.length !== 1)
5832
+ return undefined;
5833
+ const sig = sigs[0];
5834
+ const own = new Set(sig.getTypeParameters());
5835
+ const outer = ctx.resolveTypeParam;
5836
+ const erased = mapType(t, {
5837
+ ...ctx,
5838
+ erasingSignature: sig,
5839
+ resolveTypeParam: (param) => (own.has(param) ? DYN : (outer?.(param) ?? null)),
5840
+ });
5841
+ return erased?.kind === "func" ? erased : undefined;
5842
+ }
5843
+ /** An OVERLOADED callable member type (`on(event: "a", h: (x: number) =>
5844
+ * void): () => void; on(event: "b", h: (x: string) => void): () => void`
5845
+ * in a program interface or type literal): two or more call signatures and
5846
+ * nothing else (no data properties, construct signatures, or index
5847
+ * signatures), every one declared in TypeScript program source. Such a
5848
+ * member keeps a record slot holding its erased runtime function
5849
+ * (erasedOverloadMemberType); calls convert per their resolved overload
5850
+ * (lowerRecordFieldCall). */
5851
+ export function isOverloadedCallableMemberType(t, checker) {
5852
+ const sigs = checker.getCallSignatures(t);
5853
+ if (sigs.length < 2)
5854
+ return false;
5855
+ if (checker.getConstructSignatures(t).length > 0 ||
5856
+ checker.getPropertiesOfType(t).length > 0 ||
5857
+ checker.getIndexInfosOfType(t).length > 0)
5858
+ return false;
5859
+ return sigs.every((sig) => {
5860
+ const decl = sig.declaration;
5861
+ if (decl === undefined)
5862
+ return false;
5863
+ if (!ts.isMethodSignatureDeclaration(decl) && !ts.isCallSignatureDeclaration(decl))
5864
+ return false;
5865
+ const file = ts.getSourceFileOfNode(decl);
5866
+ return !file.isDeclarationFile && !isJsSourceFile(file);
5867
+ });
5868
+ }
5869
+ /** Scalar arms an overload join may combine into one union. */
5870
+ const OVERLOAD_JOIN_SCALARS = new Set(["f64", "string", "bool", "undefinedT", "nullT"]);
5871
+ /** The join of one position's types across an overload set: equal types
5872
+ * stay; scalar mixes form their union; anything else is `unknown` when
5873
+ * every joined type crosses the checked-dynamic boundary in both directions
5874
+ * (the call site converts into the slot, the implementation converts out
5875
+ * of it). Differing callbacks (`(x: number) => void` beside `(x: string) =>
5876
+ * void`) therefore travel as checked function values, which any
5877
+ * implementation's own callback type adapts from. Null when no join
5878
+ * exists. */
5879
+ function joinOverloadTypes(types, ctx) {
5880
+ const first = types[0];
5881
+ if (types.every((t) => typeEquals(t, first)))
5882
+ return first;
5883
+ const getRecord = (id) => ctx.shapes.get(id);
5884
+ const getUnion = (id) => ctx.unions.get(id);
5885
+ const arms = new Map();
5886
+ let scalar = true;
5887
+ for (const t of types) {
5888
+ const parts = t.kind === "union" ? (ctx.unions.get(t.unionId)?.arms ?? []) : [t];
5889
+ if (parts.length === 0)
5890
+ scalar = false;
5891
+ for (const part of parts) {
5892
+ if (!OVERLOAD_JOIN_SCALARS.has(part.kind))
5893
+ scalar = false;
5894
+ arms.set(typeKey(part), part);
5895
+ }
5896
+ }
5897
+ if (scalar && [...arms.values()].some((arm) => !isUnitType(arm))) {
5898
+ const sorted = [...arms.values()].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
5899
+ return { kind: "union", unionId: ctx.unions.intern(sorted) };
5900
+ }
5901
+ if (types.every((t) => t.kind === "dyn" ||
5902
+ (t.kind !== "void" &&
5903
+ canConvertToDyn(t, getRecord, getUnion) &&
5904
+ canDynCheckTo(t, getRecord, getUnion))))
5905
+ return DYN;
5906
+ return null;
5907
+ }
5908
+ /** An overloaded member's runtime type (isOverloadedCallableMemberType).
5909
+ * JavaScript stores ONE function under the member; overload signatures only
5910
+ * constrain call sites. The slot's type joins the overloads per parameter
5911
+ * position and result (joinOverloadTypes), and a position some overloads
5912
+ * omit is optional. Each overload's own type parameters erase to `unknown`
5913
+ * first. Calls pick their overload statically, convert arguments into the
5914
+ * slot's parameter types and the result back to the overload's; an
5915
+ * implementation converts into the slot like any function value. Undefined
5916
+ * when the set does not join (rest parameters, a void result beside a
5917
+ * value result, a component outside the checked-dynamic boundary): the
5918
+ * member keeps its fence. */
5919
+ export function erasedOverloadMemberType(t, ctx) {
5920
+ const funcs = [];
5921
+ for (const sig of ctx.checker.getCallSignatures(t)) {
5922
+ const own = new Set(sig.getTypeParameters());
5923
+ const outer = ctx.resolveTypeParam;
5924
+ const mapped = mapCallSignature(sig, own.size === 0
5925
+ ? ctx
5926
+ : {
5927
+ ...ctx,
5928
+ erasingSignature: sig,
5929
+ resolveTypeParam: (param) => (own.has(param) ? DYN : (outer?.(param) ?? null)),
5930
+ });
5931
+ if (mapped?.kind !== "func" || mapped.rest === true || mapped.argumentsAll === true)
5932
+ return undefined;
5933
+ funcs.push(mapped);
5934
+ }
5935
+ const arity = Math.max(...funcs.map((f) => f.params.length));
5936
+ const params = [];
5937
+ for (let i = 0; i < arity; i++) {
5938
+ const present = funcs.filter((f) => i < f.params.length).map((f) => f.params[i]);
5939
+ let param = joinOverloadTypes(present, ctx);
5940
+ if (param !== null && present.length < funcs.length && param.kind !== "dyn")
5941
+ param = withUndefinedArm(param, ctx.unions);
5942
+ if (param === null)
5943
+ return undefined;
5944
+ params.push(param);
5945
+ }
5946
+ const voids = funcs.filter((f) => f.ret.kind === "void").length;
5947
+ if (voids !== 0 && voids !== funcs.length)
5948
+ return undefined;
5949
+ const ret = voids === funcs.length
5950
+ ? VOID
5951
+ : joinOverloadTypes(funcs.map((f) => f.ret), ctx);
5952
+ if (ret === null)
5953
+ return undefined;
5954
+ return funcOf(params, ret);
5955
+ }
5956
+ /** Why an overloaded member's set has no erased type
5957
+ * (erasedOverloadMemberType): the first overload, and within it the first
5958
+ * parameter or result, that does not map; otherwise the join itself. A
5959
+ * message tail after "its member 'name'". */
5960
+ function describeOverloadSetBlocker(t, ctx) {
5961
+ const { checker } = ctx;
5962
+ for (const sig of checker.getCallSignatures(t)) {
5963
+ const own = new Set(sig.getTypeParameters());
5964
+ const outer = ctx.resolveTypeParam;
5965
+ const sigCtx = own.size === 0
5966
+ ? ctx
5967
+ : {
5968
+ ...ctx,
5969
+ erasingSignature: sig,
5970
+ resolveTypeParam: (param) => (own.has(param) ? DYN : (outer?.(param) ?? null)),
5971
+ };
5972
+ const mapped = mapCallSignature(sig, sigCtx);
5973
+ if (mapped?.kind === "func" && mapped.rest !== true && mapped.argumentsAll !== true)
5974
+ continue;
5975
+ const decl = sig.declaration;
5976
+ const spelled = decl ? ts.getTextOfNode(decl).replace(/\s+/g, " ").replace(/;$/, "") : "";
5977
+ const which = spelled ? `overload '${spelled}'` : "one overload";
5978
+ if (mapped?.kind === "func")
5979
+ return `is an overload set, and its ${which} has a rest parameter (an overload set stores one fixed-arity function)`;
5980
+ for (const param of sig.getParameters()) {
5981
+ const paramTs = checker.getTypeOfSymbol(param);
5982
+ if (!mapType(paramTs, sigCtx))
5983
+ return `is an overload set, and its ${which} has parameter '${ts.symbolName(param)}' of type '${checker.typeToString(paramTs)}', which does not compile`;
5984
+ }
5985
+ const retTs = checker.getReturnTypeOfSignature(sig);
5986
+ return `is an overload set, and its ${which} returns '${checker.typeToString(retTs)}', which does not compile`;
5987
+ }
5988
+ return "is an overload set whose signatures do not join into one stored function (a void result beside a value result, or positions whose differing types do not cross the checked-dynamic boundary)";
5989
+ }
4552
5990
  function mapRecordType(widened, ctx) {
4553
5991
  const { shapes } = ctx;
4554
5992
  // A type whose recursive shape already finalized answers its id straight
@@ -4587,10 +6025,9 @@ function mapRecordType(widened, ctx) {
4587
6025
  // checker-type identity — fence recursive generic-open shapes.
4588
6026
  if (contextResolutions !== sensitivityAtEntry)
4589
6027
  return null;
4590
- return {
4591
- kind: "record",
4592
- shapeId: shapes.finalizeRecursive(widened, inner.fields, inner.indexValue, inner.declaredOrder),
4593
- };
6028
+ const recursive = shapes.finalizeRecursive(widened, inner.fields, inner.indexValue, inner.declaredOrder);
6029
+ adoptAccessorOrder(shapes.get(recursive), inner.accessorOrder);
6030
+ return { kind: "record", shapeId: recursive };
4594
6031
  }
4595
6032
  // A record with no typed payload contract is a view of an existing
4596
6033
  // object, including across parameters and returns. Building a native
@@ -4601,18 +6038,294 @@ function mapRecordType(widened, ctx) {
4601
6038
  inner.fields.every((field) => field.type.kind === "dyn") &&
4602
6039
  (inner.indexValue === undefined || inner.indexValue.kind === "dyn"))
4603
6040
  return DYN;
6041
+ const covered = coveredOptionalFieldsShape(widened, inner, ctx);
6042
+ if (covered !== null)
6043
+ return { kind: "record", shapeId: covered };
6044
+ const merged = dictSpreadLiteralShape(widened, inner, ctx);
6045
+ if (merged === "dyn")
6046
+ return DYN;
6047
+ if (merged !== null)
6048
+ return { kind: "record", shapeId: merged };
4604
6049
  const refined = refinedConstituentShape(widened, inner, ctx);
4605
6050
  if (refined !== null)
4606
6051
  return { kind: "record", shapeId: refined };
4607
- return {
4608
- kind: "record",
4609
- shapeId: shapes.intern(inner.fields, false, inner.indexValue, inner.declaredOrder),
4610
- };
6052
+ const shapeId = shapes.intern(inner.fields, false, inner.indexValue, inner.declaredOrder);
6053
+ adoptAccessorOrder(shapes.get(shapeId), inner.accessorOrder);
6054
+ return { kind: "record", shapeId };
4611
6055
  }
4612
6056
  finally {
4613
6057
  shapes.inProgress.delete(widened);
4614
6058
  }
4615
6059
  }
6060
+ /** An index signature already describes every OPTIONAL declared member
6061
+ * whose type is its slot type: @types/node's `ProcessEnv extends
6062
+ * Dict<string> { TZ?: string }` and every spread of it, or a declared
6063
+ * environment `{ CI?: string } & Dictionary<string>`. At runtime such a
6064
+ * member is just another key, so the shape interns as the pure
6065
+ * index-signature record. Its slot admits undefined, as the optional
6066
+ * members do (`env.CI = undefined` keeps the key). A hybrid layout would
6067
+ * give each member a struct slot, which enumerates before the overflow
6068
+ * keys (Node keeps one insertion order) and makes `delete` and spread
6069
+ * answer differently for declared and undeclared keys. Required members,
6070
+ * and members typed otherwise than the slot (whose reads the slot type
6071
+ * could not give back), keep the hybrid shape. */
6072
+ function coveredOptionalFieldsShape(widened, parts, ctx) {
6073
+ const slot = parts.indexValue;
6074
+ if (!slot || parts.fields.length === 0)
6075
+ return null;
6076
+ const { checker, shapes, unions } = ctx;
6077
+ // The members' common type must be the slot plus undefined. Read it off
6078
+ // the members (already interned) rather than building it: a hybrid that
6079
+ // does not qualify must not intern anything new.
6080
+ const optionalSlot = parts.fields[0].type;
6081
+ if (!parts.fields.every((field) => typeEquals(field.type, optionalSlot)))
6082
+ return null;
6083
+ if (optionalSlot.kind !== "union" || unions.armTag(optionalSlot.unionId, UNDEFINED_T) < 0)
6084
+ return null;
6085
+ const memberArms = unions.get(optionalSlot.unionId)?.arms ?? [];
6086
+ const slotArms = slot.kind === "union" ? (unions.get(slot.unionId)?.arms ?? []) : isUnitType(slot) ? [] : [slot];
6087
+ const definedArms = memberArms.filter((arm) => arm.kind !== "undefinedT");
6088
+ const slotDefined = slotArms.filter((arm) => arm.kind !== "undefinedT");
6089
+ if (definedArms.length === 0 ||
6090
+ definedArms.length !== slotDefined.length ||
6091
+ !slotDefined.every((arm) => definedArms.some((other) => typeEquals(arm, other))))
6092
+ return null;
6093
+ if (!isSupportedIndexValue(optionalSlot))
6094
+ return null;
6095
+ const props = checker.getPropertiesOfType(widened);
6096
+ if (props.length !== parts.fields.length)
6097
+ return null;
6098
+ if (!props.every((p) => (p.flags & ts.SymbolFlags.Optional) !== 0))
6099
+ return null;
6100
+ return shapes.intern([], false, optionalSlot, []);
6101
+ }
6102
+ /** The type of an object literal that spreads an index-signature record
6103
+ * (`{ ...tags, bucket: b, status }`, the metric-tags idiom). The checker
6104
+ * drops the signature and types the literal by its explicit members only,
6105
+ * but at run time the object holds every key the spread copied, in one
6106
+ * insertion order. Such a literal maps to the pure index-signature record
6107
+ * whose slot joins the spread slots and the member types, so the merge,
6108
+ * every enumeration and keyed writes see the same keys Node does. A
6109
+ * member read still answers its member type: members written after the
6110
+ * spreads always win, and a member written before a spread must have that
6111
+ * spread's slot type, so an override cannot change its type. The join
6112
+ * covers scalar and unit types only; other literals keep their shape and
6113
+ * the spread fence. */
6114
+ function dictSpreadLiteralShape(widened, parts, ctx) {
6115
+ if (parts.indexValue)
6116
+ return null;
6117
+ const symbol = widened.getSymbol();
6118
+ if (!symbol || (symbol.flags & ts.SymbolFlags.ObjectLiteral) === 0)
6119
+ return null;
6120
+ const literal = symbol.declarations.find((d) => ts.isObjectLiteralExpression(d));
6121
+ if (!literal)
6122
+ return null;
6123
+ const { checker, shapes, unions } = ctx;
6124
+ const props = literal.properties.nodes;
6125
+ if (!props.some((p) => ts.isSpreadAssignment(p)))
6126
+ return null;
6127
+ // Decide on checker types alone before mapping anything: object literals
6128
+ // with ordinary spreads are everywhere, and mapping their sources here
6129
+ // would intern types out of their usual order.
6130
+ // A literal written into a typed index-signature slot already lowers into
6131
+ // it (the merge into the contextual record); its own type keeps its
6132
+ // mapping.
6133
+ const contextualRaw = checker.getContextualType(literal);
6134
+ const contextual = contextualRaw ? checker.getNonNullableType(contextualRaw) : undefined;
6135
+ // A literal written into a declared slot lowers into that slot (a typed
6136
+ // index-signature record merges into it, a declared record converts),
6137
+ // and its own type keeps its mapping. Only a literal with no declared
6138
+ // destination (an unannotated binding, a type parameter, `any` or
6139
+ // `unknown`, an unknown-valued record) is built by its own type.
6140
+ // A generic argument's context is the instantiated parameter: the
6141
+ // literal's own type when the type argument was inferred from it.
6142
+ const ownContext = contextual !== undefined &&
6143
+ (contextual === widened || contextual.getSymbol()?.declarations.includes(literal) === true);
6144
+ if (contextual &&
6145
+ !ownContext &&
6146
+ !(contextual.flags & (ts.TypeFlags.TypeParameter | ts.TypeFlags.Any | ts.TypeFlags.Unknown))) {
6147
+ const infos = checker.getIndexInfosOfType(contextual);
6148
+ const unknownValued = infos.length > 0 &&
6149
+ infos.every((info) => (info.type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0);
6150
+ if (!unknownValued)
6151
+ return null;
6152
+ }
6153
+ const kinds = props.map((p) => ts.isSpreadAssignment(p) ? spreadSourceKindTs(checker, p.expression) : "member");
6154
+ if (kinds.some((k) => k === null) || !kinds.includes("dict"))
6155
+ return null;
6156
+ const dictSlotOf = (e) => {
6157
+ const t = checker.getNonNullableType(checker.getTypeAtLocation(e));
6158
+ if (checker.getPropertiesOfType(t).length === 0) {
6159
+ const infos = checker.getIndexInfosOfType(t);
6160
+ if (infos.length !== 1 || !(infos[0].keyType.flags & ts.TypeFlags.String))
6161
+ return null;
6162
+ return mapType(infos[0].type, ctx);
6163
+ }
6164
+ // Another such literal's type (`{ ...tags, repo }` over a binding
6165
+ // initialized by `{ ...base, plan }`) is stored as the same kind of
6166
+ // pure index-signature record.
6167
+ if (t === widened)
6168
+ return null;
6169
+ const mapped = mapType(t, ctx);
6170
+ if (mapped?.kind === "dyn")
6171
+ return DYN;
6172
+ const shape = mapped?.kind === "record" ? shapes.get(mapped.shapeId) : undefined;
6173
+ return shape?.indexValue && shape.fields.length === 0 && !shape.tuple ? shape.indexValue : null;
6174
+ };
6175
+ const arms = new Map();
6176
+ const addArms = (t) => {
6177
+ const list = t.kind === "union" ? (unions.get(t.unionId)?.arms ?? []) : [t];
6178
+ for (const arm of list) {
6179
+ if (!OVERLOAD_JOIN_SCALARS.has(arm.kind))
6180
+ return false;
6181
+ arms.set(typeKey(arm), arm);
6182
+ }
6183
+ return true;
6184
+ };
6185
+ const before = [];
6186
+ // An unknown-valued spread (`Record<string, unknown>`, or another such
6187
+ // literal) makes the object the checked-dynamic value: it is built like
6188
+ // a JavaScript object literal (copy each spread's own keys in order), and
6189
+ // member reads check their declared types.
6190
+ let unknownValued = false;
6191
+ for (const [i, p] of props.entries()) {
6192
+ // A fixed-shape or conditional spread contributes its own members,
6193
+ // which the checker already types exactly (they are in `parts`).
6194
+ if (kinds[i] === "record") {
6195
+ // Its members may be overwritten by a later dict spread, like members
6196
+ // written before one.
6197
+ before.push(...spreadMemberNamesTs(checker, p.expression));
6198
+ continue;
6199
+ }
6200
+ if (ts.isSpreadAssignment(p)) {
6201
+ const slot = dictSlotOf(p.expression);
6202
+ if (slot?.kind === "dyn") {
6203
+ unknownValued = true;
6204
+ continue;
6205
+ }
6206
+ if (!slot)
6207
+ return null;
6208
+ if (!addArms(slot)) {
6209
+ // A slot outside the scalar join still has the checked-dynamic
6210
+ // representation when it converts to it.
6211
+ if (!canConvertToDyn(slot, (id) => shapes.get(id), (id) => unions.get(id)))
6212
+ return null;
6213
+ unknownValued = true;
6214
+ }
6215
+ // A member written before this spread may be overwritten by it: the
6216
+ // typed join keeps member types only where the slot is that type;
6217
+ // otherwise the checked-dynamic object (whose member reads check
6218
+ // their types) holds whatever the spread wrote.
6219
+ for (const name of before) {
6220
+ const field = parts.fields.find((f) => f.name === name);
6221
+ if (!field)
6222
+ return null;
6223
+ if (!typeEquals(field.type, slot))
6224
+ unknownValued = true;
6225
+ }
6226
+ continue;
6227
+ }
6228
+ if (!(ts.isPropertyAssignment(p) || ts.isShorthandPropertyAssignment(p)))
6229
+ return null;
6230
+ const name = p.name;
6231
+ if (!(ts.isIdentifier(name) || ts.isStringLiteral(name)))
6232
+ return null;
6233
+ before.push(name.text);
6234
+ }
6235
+ if (parts.fields.some((f) => f.name.startsWith("%")))
6236
+ return null;
6237
+ // Members outside the scalar join (an array of labels beside the tags)
6238
+ // make the object the checked-dynamic value too.
6239
+ if (!unknownValued && !parts.fields.every((f) => addArms(f.type)))
6240
+ unknownValued = true;
6241
+ if (unknownValued) {
6242
+ const getRecord = (id) => shapes.get(id);
6243
+ const getUnion = (id) => unions.get(id);
6244
+ return parts.fields.every((f) => f.type.kind === "dyn" || canConvertToDyn(f.type, getRecord, getUnion))
6245
+ ? "dyn"
6246
+ : null;
6247
+ }
6248
+ for (const field of parts.fields)
6249
+ if (!addArms(field.type))
6250
+ return null;
6251
+ if (![...arms.values()].some((arm) => !isUnitType(arm)))
6252
+ return null;
6253
+ const sorted = [...arms.values()].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
6254
+ const slot = sorted.length === 1 ? sorted[0] : { kind: "union", unionId: unions.intern(sorted) };
6255
+ return shapes.intern([], false, slot, []);
6256
+ }
6257
+ /** How a spread source contributes to dictSpreadLiteralShape, judged on
6258
+ * checker types only: "dict" for a pure string index signature or another
6259
+ * literal that spreads one, "record" for a fixed object shape or a
6260
+ * conditional spread (`...(c && { k: v })`), null otherwise. */
6261
+ function spreadSourceKindTs(checker, e) {
6262
+ if (dictSpreadSourceTs(checker, e, 0))
6263
+ return "dict";
6264
+ let inner = e;
6265
+ while (ts.isParenthesizedExpression(inner))
6266
+ inner = inner.expression;
6267
+ if ((ts.isBinaryExpression(inner) &&
6268
+ inner.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) ||
6269
+ ts.isConditionalExpression(inner))
6270
+ return "record";
6271
+ const t = checker.getNonNullableType(checker.getTypeAtLocation(e));
6272
+ if ((t.flags & ts.TypeFlags.Object) === 0 || t.isUnionType())
6273
+ return null;
6274
+ if (checker.getIndexInfosOfType(t).length > 0)
6275
+ return null;
6276
+ if (checker.getCallSignatures(t).length > 0 || checker.getConstructSignatures(t).length > 0)
6277
+ return null;
6278
+ const symbol = t.getSymbol();
6279
+ if (symbol && (symbol.flags & ts.SymbolFlags.Class) !== 0)
6280
+ return null;
6281
+ return "record";
6282
+ }
6283
+ /** The member names a fixed-shape or conditional spread contributes. */
6284
+ function spreadMemberNamesTs(checker, e) {
6285
+ let inner = e;
6286
+ while (ts.isParenthesizedExpression(inner))
6287
+ inner = inner.expression;
6288
+ const literals = [];
6289
+ if (ts.isBinaryExpression(inner))
6290
+ literals.push(inner.right);
6291
+ else if (ts.isConditionalExpression(inner))
6292
+ literals.push(inner.whenTrue, inner.whenFalse);
6293
+ else
6294
+ literals.push(inner);
6295
+ const names = [];
6296
+ for (const l of literals) {
6297
+ const t = checker.getNonNullableType(checker.getTypeAtLocation(l));
6298
+ for (const property of checker.getPropertiesOfType(t))
6299
+ names.push(ts.symbolName(property));
6300
+ }
6301
+ return names;
6302
+ }
6303
+ /** A spread source the checker types as a pure string index signature,
6304
+ * or as another object literal that spreads one (dictSpreadLiteralShape),
6305
+ * judged on checker types only. */
6306
+ function dictSpreadSourceTs(checker, e, depth) {
6307
+ const t = checker.getNonNullableType(checker.getTypeAtLocation(e));
6308
+ if (checker.getPropertiesOfType(t).length === 0) {
6309
+ const infos = checker.getIndexInfosOfType(t);
6310
+ return infos.length === 1 && (infos[0].keyType.flags & ts.TypeFlags.String) !== 0;
6311
+ }
6312
+ if (depth > 4)
6313
+ return false;
6314
+ const symbol = t.getSymbol();
6315
+ if (!symbol || (symbol.flags & ts.SymbolFlags.ObjectLiteral) === 0)
6316
+ return false;
6317
+ const literal = symbol.declarations.find((d) => ts.isObjectLiteralExpression(d));
6318
+ if (!literal)
6319
+ return false;
6320
+ const spreads = literal.properties.nodes.filter((p) => ts.isSpreadAssignment(p));
6321
+ return (spreads.length > 0 &&
6322
+ spreads.every((p) => dictSpreadSourceTs(checker, p.expression, depth + 1)));
6323
+ }
6324
+ /** The first-seen accessor key order of a shape with accessor slots. */
6325
+ function adoptAccessorOrder(shape, order) {
6326
+ if (shape !== undefined && order !== undefined && shape.accessorOrder === undefined)
6327
+ shape.accessorOrder = order;
6328
+ }
4616
6329
  /** A refinement intersection (`Expr & { kind: "mul" }`, which the checker
4617
6330
  * reduces to `Mul & { kind: "mul" }`) keeps the shape of the constituent it
4618
6331
  * refines when the refinement changes no field's representation. Recursive
@@ -4626,12 +6339,12 @@ function refinedConstituentShape(widened, parts, ctx) {
4626
6339
  if (!widened.isIntersectionType())
4627
6340
  return null;
4628
6341
  const { checker, shapes } = ctx;
4629
- const names = checker.getPropertiesOfType(widened).map((prop) => prop.name);
6342
+ const names = checker.getPropertiesOfType(widened).map((prop) => ts.symbolName(prop));
4630
6343
  let found = null;
4631
6344
  for (const part of ts.constituentTypes(widened)) {
4632
6345
  if ((part.flags & ts.TypeFlags.Object) === 0 || shapes.inProgress.has(part))
4633
6346
  continue;
4634
- const own = new Set(checker.getPropertiesOfType(part).map((prop) => prop.name));
6347
+ const own = new Set(checker.getPropertiesOfType(part).map((prop) => ts.symbolName(prop)));
4635
6348
  if (own.size !== names.length || !names.every((name) => own.has(name)))
4636
6349
  continue;
4637
6350
  const mapped = mapType(part, ctx);
@@ -4651,6 +6364,29 @@ function refinedConstituentShape(widened, parts, ctx) {
4651
6364
  }
4652
6365
  return found;
4653
6366
  }
6367
+ /** The optional `undefined` members widening adds to an object literal's
6368
+ * type for properties only its sibling literals declare (`[{ a: 1 }, { b: 2
6369
+ * }]` gives the first `b?: undefined`). They are never own keys of the
6370
+ * literal's value, so they go after the declared members, by name. Where
6371
+ * the checker lists them is not observable: TypeScript 7.0.2 orders them
6372
+ * by the literal its checker widened first, TypeScript 7.1 by the sibling
6373
+ * that declares them. */
6374
+ function wideningAddedProperties(type, props, ctx) {
6375
+ const added = new Set();
6376
+ const literal = type.getSymbol()?.declarations.find(ts.isObjectLiteralExpression);
6377
+ if (literal === undefined || literal.properties.nodes.some(ts.isSpreadAssignment))
6378
+ return added;
6379
+ for (const prop of props) {
6380
+ if ((prop.flags & ts.SymbolFlags.Optional) === 0 || prop.declarations.length === 0)
6381
+ continue;
6382
+ if (prop.declarations.some((d) => d.parent === literal))
6383
+ continue;
6384
+ if ((ctx.checker.getTypeOfSymbol(prop).flags & ts.TypeFlags.Undefined) === 0)
6385
+ continue;
6386
+ added.add(ts.symbolName(prop));
6387
+ }
6388
+ return added;
6389
+ }
4654
6390
  function mapRecordTypeInner(widened, ctx) {
4655
6391
  const { checker, shapes } = ctx;
4656
6392
  if (checker.getConstructSignatures(widened).length > 0)
@@ -4703,7 +6439,7 @@ function mapRecordTypeInner(widened, ctx) {
4703
6439
  for (const info of indexInfos) {
4704
6440
  if (!stringKey(info.keyType) && !(info.keyType.flags & ts.TypeFlags.Number))
4705
6441
  return null;
4706
- const iv = mapType(info.valueType, ctx);
6442
+ const iv = mapType(info.type, ctx);
4707
6443
  // JSONValue>` (a package's own JSON alias) and `Record<string, any>`
4708
6444
  if (!iv || !isSupportedIndexValue(iv))
4709
6445
  return null;
@@ -4779,7 +6515,7 @@ function mapRecordTypeInner(widened, ctx) {
4779
6515
  // stance), records of other shapes at theirs — the declaration itself is
4780
6516
  // representable.
4781
6517
  const anonSym = widened.getSymbol();
4782
- const anonymousEmpty = (anonSym === undefined || checker.declarationsOf(anonSym).length === 0) &&
6518
+ const anonymousEmpty = (anonSym === undefined || anonSym.declarations.length === 0) &&
4783
6519
  !widened.isIntersectionType() &&
4784
6520
  indexValue === undefined &&
4785
6521
  checker.getPropertiesOfType(widened).length === 0;
@@ -4794,7 +6530,7 @@ function mapRecordTypeInner(widened, ctx) {
4794
6530
  return DYN;
4795
6531
  // Symbol-keyed records use the checked object's descriptor table. A
4796
6532
  // checker-internal __@ name is not a string field in a native struct.
4797
- if (props.some((property) => property.name.startsWith("__@")))
6533
+ if (props.some((property) => ts.symbolName(property).startsWith("__@")))
4798
6534
  return DYN;
4799
6535
  // A computed shape with NO members is not a real empty record: inside a
4800
6536
  // generic body `Partial<T>` resolves to no members at all (keyof T is
@@ -4821,8 +6557,7 @@ function mapRecordTypeInner(widened, ctx) {
4821
6557
  indexValue === undefined &&
4822
6558
  checker.getCallSignatures(widened).length === 0 &&
4823
6559
  checker.getConstructSignatures(widened).length === 0 &&
4824
- !(anonSym !== undefined &&
4825
- checker.declarationsOf(anonSym).some((d) => ts.isObjectLiteralExpression(d)))) {
6560
+ !(anonSym !== undefined && anonSym.declarations.some((d) => ts.isObjectLiteralExpression(d)))) {
4826
6561
  return DYN;
4827
6562
  }
4828
6563
  const fields = [];
@@ -4843,7 +6578,7 @@ function mapRecordTypeInner(widened, ctx) {
4843
6578
  // their existing paths (the CJS export-table narrowing and the
4844
6579
  // checked-dynamic fallback), and .d.ts declarations stay out with
4845
6580
  // the rest of the lib's type worlds.
4846
- const decls = checker.declarationsOf(p);
6581
+ const decls = p.declarations;
4847
6582
  const getDecl = decls.find((d) => ts.isGetAccessorDeclaration(d));
4848
6583
  const setDecl = decls.find((d) => ts.isSetAccessorDeclaration(d));
4849
6584
  const accessorOwned = decls.length > 0 &&
@@ -4852,13 +6587,13 @@ function mapRecordTypeInner(widened, ctx) {
4852
6587
  (ts.isObjectLiteralExpression(d.parent) ||
4853
6588
  ts.isInterfaceDeclaration(d.parent) ||
4854
6589
  d.parent.kind === ts.SyntaxKind.TypeLiteral) &&
4855
- !d.getSourceFile().isDeclarationFile &&
4856
- !isJsSourceFile(d.getSourceFile()));
6590
+ !ts.getSourceFileOfNode(d).isDeclarationFile &&
6591
+ !isJsSourceFile(ts.getSourceFileOfNode(d)));
4857
6592
  if (!accessorOwned || (!getDecl && !setDecl))
4858
6593
  return null;
4859
6594
  // Symbol-keyed accessors have no foldable literal name to fill at
4860
6595
  // the literal — no slot to make.
4861
- if (p.name.startsWith("__@"))
6596
+ if (ts.symbolName(p).startsWith("__@"))
4862
6597
  return null;
4863
6598
  // An index-signature shape stores accessor NAMES nowhere the keyed
4864
6599
  // read/walk machinery can answer (the overflow would miss where
@@ -4873,7 +6608,7 @@ function mapRecordTypeInner(widened, ctx) {
4873
6608
  }
4874
6609
  let writeT = null;
4875
6610
  if (setDecl) {
4876
- const param = setDecl.parameters[0];
6611
+ const param = setDecl.parameters.nodes[0];
4877
6612
  if (!param)
4878
6613
  return null;
4879
6614
  writeT = mapType(checker.getTypeAtLocation(param), ctx);
@@ -4886,9 +6621,9 @@ function mapRecordTypeInner(widened, ctx) {
4886
6621
  return null;
4887
6622
  }
4888
6623
  if (readT !== null || getDecl)
4889
- fields.push({ name: `%get:${p.name}`, type: funcOf([], readT ?? VOID) });
6624
+ fields.push({ name: `%get:${ts.symbolName(p)}`, type: funcOf([], readT ?? VOID) });
4890
6625
  if (writeT !== null)
4891
- fields.push({ name: `%set:${p.name}`, type: funcOf([writeT], VOID) });
6626
+ fields.push({ name: `%set:${ts.symbolName(p)}`, type: funcOf([writeT], VOID) });
4892
6627
  continue;
4893
6628
  }
4894
6629
  // Computed shapes carry provenance per MEMBER: a utility type over a
@@ -4896,9 +6631,9 @@ function mapRecordTypeInner(widened, ctx) {
4896
6631
  // a data shape. Synthesized members (a literal-key Record's) have no
4897
6632
  // declarations and pass.
4898
6633
  if (computed &&
4899
- checker.declarationsOf(p).some((d) => {
4900
- const sf = d.getSourceFile();
4901
- return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf);
6634
+ p.declarations.some((d) => {
6635
+ const sf = ts.getSourceFileOfNode(d);
6636
+ return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf) && !packageTypeFile(sf, ctx);
4902
6637
  })) {
4903
6638
  return null;
4904
6639
  }
@@ -4907,9 +6642,16 @@ function mapRecordTypeInner(widened, ctx) {
4907
6642
  // can hold them — see isGenericCallableMemberType): the shape keeps
4908
6643
  // its data fields, and calls of the member monomorphize per call
4909
6644
  // site against the defining object literal's declaration.
4910
- if (isGenericCallableMemberType(fieldTs, checker))
6645
+ // OVERLOADED members hold their erased runtime function (see
6646
+ // erasedOverloadMemberType); a set that does not join fails the
6647
+ // shape as before.
6648
+ let pt = isGenericCallableMemberType(fieldTs, checker)
6649
+ ? erasedGenericMemberType(fieldTs, ctx)
6650
+ : isOverloadedCallableMemberType(fieldTs, checker)
6651
+ ? (erasedOverloadMemberType(fieldTs, ctx) ?? null)
6652
+ : mapType(fieldTs, ctx);
6653
+ if (pt === undefined)
4911
6654
  continue;
4912
- let pt = mapType(fieldTs, ctx);
4913
6655
  // tsgo PANICS computing `readonly []` through the symbol-type query
4914
6656
  // (the TupleType conversion — the facade's panic fence answers
4915
6657
  // `any`), which would absorb the whole shape into the dynamic tier.
@@ -4919,7 +6661,7 @@ function mapRecordTypeInner(widened, ctx) {
4919
6661
  // unit-element array; see the `[] as const` rule there).
4920
6662
  if (pt === null &&
4921
6663
  (fieldTs.flags & ts.TypeFlags.Any) !== 0 &&
4922
- constAssertedEmptyArrayProp(p, ctx)) {
6664
+ constAssertedEmptyArrayProp(p)) {
4923
6665
  pt = arrayOf(unitOnlyUnion(ctx.unions));
4924
6666
  }
4925
6667
  if (pt === null && (fieldTs.flags & ts.TypeFlags.Any) !== 0)
@@ -4940,10 +6682,10 @@ function mapRecordTypeInner(widened, ctx) {
4940
6682
  // A DATA property spelled like a reserved accessor slot (`{ "%get:x":
4941
6683
  // v }` — a string-literal key): mapping it would collide with the
4942
6684
  // accessor dispatch, so the shape stays unmapped.
4943
- if (accessorSlotProp(p.name) !== null)
6685
+ if (accessorSlotProp(ts.symbolName(p)) !== null)
4944
6686
  return null;
4945
6687
  // an options record with `signal?: AbortSignal` must not turn its
4946
- fields.push({ name: p.name, type: pt });
6688
+ fields.push({ name: ts.symbolName(p), type: pt });
4947
6689
  }
4948
6690
  // getPropertiesOfType yields DECLARATION order (interface/alias/literal
4949
6691
  // source order) — captured before the canonical sort so Object.keys/
@@ -4954,9 +6696,23 @@ function mapRecordTypeInner(widened, ctx) {
4954
6696
  // indices, from folded numeric computed keys and quoted numeric keys)
4955
6697
  // enumerate FIRST ascending, then string keys in insertion order
4956
6698
  // (OrdinaryOwnPropertyKeys) — Object.keys/JSON/inspect all read it.
4957
- const declaredOrder = esOwnKeyOrder(fields.filter((f) => accessorSlotProp(f.name) === null).map((f) => f.name));
6699
+ const widenedAbsent = wideningAddedProperties(widened, props, ctx);
6700
+ const declaredOrder = esOwnKeyOrder(fields
6701
+ .filter((f) => accessorSlotProp(f.name) === null && !widenedAbsent.has(f.name))
6702
+ .map((f) => f.name)
6703
+ .concat([...widenedAbsent].sort()));
6704
+ // With accessors: every own key in that order, an accessor property
6705
+ // named once for its get/set pair (the checked-dynamic copy lists it).
6706
+ const accessorOrder = fields.some((f) => accessorSlotProp(f.name) !== null)
6707
+ ? esOwnKeyOrder([...new Set(fields.map((f) => accessorSlotProp(f.name)?.prop ?? f.name))])
6708
+ : undefined;
4958
6709
  fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
4959
- return { fields, ...(indexValue ? { indexValue } : {}), declaredOrder };
6710
+ return {
6711
+ fields,
6712
+ ...(indexValue ? { indexValue } : {}),
6713
+ declaredOrder,
6714
+ ...(accessorOrder ? { accessorOrder } : {}),
6715
+ };
4960
6716
  }
4961
6717
  }
4962
6718
  /* ── Component-fence classification (SC2009) ───────────────────────────────
@@ -5006,9 +6762,63 @@ function dynSubsumableUnionArm(arm, ctx) {
5006
6762
  return false;
5007
6763
  }
5008
6764
  }
6765
+ /** A parameter of a function type that is the default of a type parameter
6766
+ * declared in node:test's standard-library declarations (MockTracker.fn's
6767
+ * `F extends Function = (...args: any[]) => undefined`). */
6768
+ function isNodeTestDefaultFunctionParam(decl, ctx) {
6769
+ const fnType = decl.parent;
6770
+ return (ts.isParameter(decl) &&
6771
+ fnType !== undefined &&
6772
+ ts.isFunctionTypeNode(fnType) &&
6773
+ fnType.parent !== undefined &&
6774
+ ts.isTypeParameterDeclaration(fnType.parent) &&
6775
+ fnType.parent.defaultType === fnType &&
6776
+ ctx.isStdlibFile(ts.getSourceFileOfNode(decl)) &&
6777
+ isDeclaredInAmbientModule(decl, "test"));
6778
+ }
6779
+ /** `any[]` (or `readonly any[]`): an array type whose element is `any`. */
6780
+ export function isAnyArrayType(t, checker) {
6781
+ if (!checker.isArrayType(t))
6782
+ return false;
6783
+ const elem = checker.getTypeArguments(t)[0];
6784
+ return elem !== undefined && (elem.flags & ts.TypeFlags.Any) !== 0;
6785
+ }
6786
+ /** The maybe-promise union rule (mapTypeInner's union rule; IR
6787
+ * maybePromiseUnionArmsOk): at most one promise arm, and when it has data
6788
+ * siblings none of them may be thenable — `await` and async `return`
6789
+ * dispatch on the union tag, so a data arm whose type declares `then`
6790
+ * would skip the thenable adoption JS performs. */
6791
+ function maybePromiseUnionOk(parts, arms, ctx) {
6792
+ if (unionContainerArmsOk(arms))
6793
+ return true;
6794
+ if (!maybePromiseUnionArmsOk(arms))
6795
+ return false;
6796
+ // A function beside a promise (`Promise<T> | (() => Promise<T>)`, the
6797
+ // assert.rejects argument) keeps its existing representation: callers
6798
+ // dispatch on callability, not on a then-able promise.
6799
+ if (arms.some((arm) => arm.kind === "func"))
6800
+ return false;
6801
+ return maybePromiseThenableArm(parts, ctx) === null;
6802
+ }
6803
+ /** The first non-promise constituent of a promise-armed union whose type
6804
+ * has a `then` member (a thenable data arm), or null. */
6805
+ function maybePromiseThenableArm(parts, ctx) {
6806
+ const { checker } = ctx;
6807
+ for (const part of parts) {
6808
+ if (part.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Null))
6809
+ continue;
6810
+ if (mapType(part, ctx)?.kind === "promise")
6811
+ continue;
6812
+ // Primitive arms answer through their wrapper prototypes, none of
6813
+ // which has `then`; object arms answer through their own members.
6814
+ if (checker.getPropertyOfType(part, "then"))
6815
+ return part;
6816
+ }
6817
+ return null;
6818
+ }
5009
6819
  /** Arm kinds with no home in a compiled union (mapTypeInner's union rule):
5010
6820
  * no runtime narrowing test exists against sibling data arms. */
5011
- function armHasUnionHome(arm, siblingCount) {
6821
+ function armHasUnionHome(arm) {
5012
6822
  switch (arm.kind) {
5013
6823
  case "void":
5014
6824
  case "union":
@@ -5017,9 +6827,6 @@ function armHasUnionHome(arm, siblingCount) {
5017
6827
  case "generator":
5018
6828
  case "dyn":
5019
6829
  return false;
5020
- // Promise data siblings still lack a supported narrowing contract.
5021
- case "promise":
5022
- return siblingCount === 0;
5023
6830
  default:
5024
6831
  return true;
5025
6832
  }
@@ -5037,11 +6844,9 @@ export function describeComponentBlocker(widened, ctx) {
5037
6844
  // `interface Map` is a record shape and keeps the record stories).
5038
6845
  const psym = widened.getSymbol();
5039
6846
  const container = psym !== undefined &&
5040
- Object.prototype.hasOwnProperty.call(STDLIB_CONTAINERS, psym.name) &&
5041
- checker
5042
- .declarationsOf(psym)
5043
- .some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))
5044
- ? psym.name
6847
+ Object.prototype.hasOwnProperty.call(STDLIB_CONTAINERS, ts.symbolName(psym)) &&
6848
+ psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
6849
+ ? ts.symbolName(psym)
5045
6850
  : undefined;
5046
6851
  if (container !== undefined) {
5047
6852
  const spec = STDLIB_CONTAINERS[container];
@@ -5126,10 +6931,24 @@ export function describeComponentBlocker(widened, ctx) {
5126
6931
  if (!mapped) {
5127
6932
  return `the union shape is supported, but its arm '${text(part)}' does not compile`;
5128
6933
  }
5129
- if (!armHasUnionHome(mapped, dataArms.length - 1)) {
6934
+ if (!armHasUnionHome(mapped)) {
5130
6935
  return `the union shape is supported, but '${text(part)}' arms have no home in a compiled union yet (no runtime narrowing test exists against sibling arms)`;
5131
6936
  }
5132
6937
  }
6938
+ const promiseArms = mappedArms.filter(({ mapped }) => mapped?.kind === "promise");
6939
+ if (promiseArms.length > 1) {
6940
+ return `the union shape is supported, but it has several promise arms ('${text(promiseArms[0].p)}' and '${text(promiseArms[1].p)}'), and a compiled union holds at most one (the union tag is the 'instanceof Promise' test)`;
6941
+ }
6942
+ if (promiseArms.length === 1 && dataArms.length > 1) {
6943
+ const callable = mappedArms.find(({ mapped }) => mapped?.kind === "func");
6944
+ if (callable) {
6945
+ return `the union shape is supported, but its function arm '${text(callable.p)}' sits beside a promise arm, and a maybe-promise union holds only data arms beside its promise`;
6946
+ }
6947
+ const thenable = maybePromiseThenableArm(parts, ctx);
6948
+ if (thenable) {
6949
+ return `the union shape is supported, but its arm '${text(thenable)}' declares 'then' beside a promise arm, so 'await' would have to adopt it as a thenable (a maybe-promise union's data arms must not be thenable)`;
6950
+ }
6951
+ }
5133
6952
  return null;
5134
6953
  }
5135
6954
  // Single-signature, non-generic function types: a parameter type or the
@@ -5142,17 +6961,17 @@ export function describeComponentBlocker(widened, ctx) {
5142
6961
  const sig = callSigs[0];
5143
6962
  if (sig.getTypeParameters().length > 0)
5144
6963
  return null;
5145
- const sigDecl = checker.signatureDeclaration(sig);
6964
+ const sigDecl = sig.declaration;
5146
6965
  if (sigDecl !== undefined &&
5147
6966
  ts.isFunctionLike(sigDecl) &&
5148
- (runtimeParameterCount(sigDecl.parameters) !== sig.getParameters().length ||
6967
+ (runtimeParameterCount(sigDecl.parameters.nodes) !== sig.getParameters().length ||
5149
6968
  bodyReadsArguments(sigDecl))) {
5150
6969
  return `the function shape is supported, but its signature is variadic ('arguments'-reading), and a compiled signature is fixed-arity`;
5151
6970
  }
5152
6971
  for (const p of sig.getParameters()) {
5153
6972
  const pTs = checker.getTypeOfSymbol(p);
5154
6973
  if (!mapType(pTs, ctx)) {
5155
- return `the function shape is supported, but its parameter '${p.name}' has type '${text(pTs)}', which does not compile`;
6974
+ return `the function shape is supported, but its parameter '${ts.symbolName(p)}' has type '${text(pTs)}', which does not compile`;
5156
6975
  }
5157
6976
  }
5158
6977
  const retTs = checker.getReturnTypeOfSignature(sig);
@@ -5189,26 +7008,33 @@ export function describeRecordMemberBlocker(widened, ctx) {
5189
7008
  // rules (mapRecordTypeInner) — no single-member claim is honest there.
5190
7009
  if ((p.flags & (ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) !== 0)
5191
7010
  continue;
5192
- if (p.name.startsWith("__@"))
7011
+ if (ts.symbolName(p).startsWith("__@"))
5193
7012
  continue;
5194
7013
  // Computed shapes over LIBRARY members (`Readonly<Date>`): the record
5195
7014
  // fence there is per-member PROVENANCE (mapRecordTypeInner's rule), not
5196
7015
  // any one member's type — that story stays with the residual fence.
5197
7016
  if (computed &&
5198
- checker.declarationsOf(p).some((d) => {
5199
- const sf = d.getSourceFile();
5200
- return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf);
7017
+ p.declarations.some((d) => {
7018
+ const sf = ts.getSourceFileOfNode(d);
7019
+ return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf) && !packageTypeFile(sf, ctx);
5201
7020
  })) {
5202
7021
  return null;
5203
7022
  }
5204
7023
  const fieldTs = checker.getTypeOfSymbol(p);
5205
- if (isGenericCallableMemberType(fieldTs, checker))
7024
+ if (isOverloadedCallableMemberType(fieldTs, checker)) {
7025
+ if (erasedOverloadMemberType(fieldTs, ctx) !== undefined)
7026
+ continue;
7027
+ return `the record shape is supported, but its member '${ts.symbolName(p)}' ${describeOverloadSetBlocker(fieldTs, ctx)}`;
7028
+ }
7029
+ let pt = isGenericCallableMemberType(fieldTs, checker)
7030
+ ? erasedGenericMemberType(fieldTs, ctx)
7031
+ : mapType(fieldTs, ctx);
7032
+ if (pt === undefined)
5206
7033
  continue;
5207
- let pt = mapType(fieldTs, ctx);
5208
7034
  if (pt?.kind === "void" && isUnitOnlyTsType(fieldTs, ctx.resolveTypeParam))
5209
7035
  pt = unitOnlyUnion(ctx.unions);
5210
7036
  if (!pt || pt.kind === "void") {
5211
- return `the record shape is supported, but its member '${p.name}' has type '${checker.typeToString(fieldTs)}', which does not compile`;
7037
+ return `the record shape is supported, but its member '${ts.symbolName(p)}' has type '${checker.typeToString(fieldTs)}', which does not compile`;
5212
7038
  }
5213
7039
  }
5214
7040
  return null;