tjs-lang 0.6.34 → 0.6.35

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tjs-lang",
3
- "version": "0.6.34",
3
+ "version": "0.6.35",
4
4
  "description": "Type-safe JavaScript dialect with runtime validation, sandboxed VM execution, and AI agent orchestration. Transpiles TypeScript to validated JS with fuel-metered execution for untrusted code.",
5
5
  "keywords": [
6
6
  "typescript",
package/src/cli/tjs.ts CHANGED
@@ -20,7 +20,7 @@ import { emit } from './commands/emit'
20
20
  import { convert } from './commands/convert'
21
21
  import { test } from './commands/test'
22
22
 
23
- const VERSION = '0.6.34'
23
+ const VERSION = '0.6.35'
24
24
 
25
25
  const HELP = `
26
26
  tjs - Typed JavaScript CLI
@@ -1811,10 +1811,19 @@ function transformParams(
1811
1811
  const name = param.name.getText(sourceFile)
1812
1812
  // Skip TypeScript's `this` pseudo-parameter (declares `this` context type)
1813
1813
  if (name === 'this') continue
1814
+ const isRest = !!param.dotDotDotToken
1814
1815
  const isOptional = !!param.questionToken || !!param.initializer
1815
1816
  const typeExample = typeToExample(param.type, undefined, warnings, ctx)
1816
1817
 
1817
- if (param.initializer) {
1818
+ if (isRest) {
1819
+ // Rest parameter: ...args: T[] → ...args: [example]
1820
+ // typeToExample already converts T[] to [example], so use directly
1821
+ if (typeExample === 'any' || typeExample === 'undefined') {
1822
+ params.push(`...${name}: [null]`)
1823
+ } else {
1824
+ params.push(`...${name}: ${typeExample}`)
1825
+ }
1826
+ } else if (param.initializer) {
1818
1827
  // Has default value - use it directly
1819
1828
  const defaultText = param.initializer.getText(sourceFile)
1820
1829
  params.push(`${name} = ${defaultText}`)
@@ -54,6 +54,44 @@ export type ObserverCallbackFunction = _PathCallbackFunction | _CallbackFunction
54
54
  }).not.toThrow()
55
55
  })
56
56
 
57
+ test('rest parameter called with no args rejected as non-array', () => {
58
+ // In tosijs elements.ts, element creators use rest params:
59
+ // function create(...contents: ElementPart[]) { ... }
60
+ //
61
+ // Calling create() with no args is valid TS — contents becomes [].
62
+ // But tjs convert emits a type check that rejects undefined:
63
+ // if (!Array.isArray(contents)) return typeError(...)
64
+ //
65
+ // This causes elements.input(), elements.div(), etc. to silently
66
+ // return a MonadicError instead of an HTMLElement, breaking all
67
+ // DOM-related tests.
68
+
69
+ const source = `
70
+ function create(...contents: string[]): string {
71
+ return contents.join(', ')
72
+ }
73
+
74
+ const result = create()
75
+ console.log(result)
76
+ `
77
+ // Step 1: TS → TJS
78
+ const tjsResult = fromTS(source, {
79
+ emitTJS: true,
80
+ filename: 'rest-param.ts',
81
+ })
82
+
83
+ // Step 2: TJS → JS
84
+ const jsResult = tjs(tjsResult.code, {
85
+ filename: 'rest-param.ts',
86
+ runTests: false,
87
+ })
88
+
89
+ // Calling with no args should work — rest params default to []
90
+ const fn = new Function(jsResult.code + '\n return result;')
91
+ const result = fn()
92
+ expect(result).toBe('') // [].join(', ') === ''
93
+ })
94
+
57
95
  test('shorthand property assignment in destructuring converts', () => {
58
96
  // component.test.ts fails to convert with:
59
97
  // "Shorthand property assignments are valid only in destructuring patterns"