Skip to content

Commit 1bf6c12

Browse files
committed
BridgeJS: chore: extend docc documentaion with namespace example
1 parent 5ca3335 commit 1bf6c12

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

Sources/JavaScriptKit/Documentation.docc/Articles/Exporting-Swift-to-JavaScript.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,93 @@ export type Exports = {
162162
}
163163
}
164164
```
165+
166+
## Using Namespaces
167+
168+
The `@JS` macro supports organizing your exported Swift code into namespaces using dot-separated strings. This allows you to create hierarchical structures in JavaScript that mirror your Swift code organization.
169+
170+
### Functions with Namespaces
171+
172+
You can export functions to specific namespaces by providing a namespace parameter:
173+
174+
```swift
175+
import JavaScriptKit
176+
177+
// Export a function to a custom namespace
178+
@JS("MyModule.Utils") func namespacedFunction() -> String {
179+
return "namespaced"
180+
}
181+
```
182+
183+
This function will be accessible in JavaScript through its namespace hierarchy:
184+
185+
```javascript
186+
// Access the function through its namespace
187+
const result = globalThis.MyModule.Utils.namespacedFunction();
188+
console.log(result); // "namespaced"
189+
```
190+
191+
The generated TypeScript declaration will reflect the namespace structure:
192+
193+
```typescript
194+
declare global {
195+
namespace MyModule {
196+
namespace Utils {
197+
function namespacedFunction(): string;
198+
}
199+
}
200+
}
201+
```
202+
203+
### Classes with Namespaces
204+
205+
For classes, you only need to specify the namespace on the top-level class declaration. All exported methods within the class will be part of that namespace:
206+
207+
```swift
208+
import JavaScriptKit
209+
210+
@JS("__Swift.Foundation") class Greeter {
211+
var name: String
212+
213+
@JS init(name: String) {
214+
self.name = name
215+
}
216+
217+
@JS func greet() -> String {
218+
return "Hello, " + self.name + "!"
219+
}
220+
221+
func changeName(name: String) {
222+
self.name = name
223+
}
224+
}
225+
```
226+
227+
In JavaScript, this class is accessible through its namespace:
228+
229+
```javascript
230+
// Create instances through namespaced constructors
231+
const greeter = new globalThis.__Swift.Foundation.Greeter("World");
232+
console.log(greeter.greet()); // "Hello, World!"
233+
```
234+
235+
The generated TypeScript declaration will organize the class within its namespace:
236+
237+
```typescript
238+
declare global {
239+
namespace __Swift {
240+
namespace Foundation {
241+
class Greeter {
242+
constructor(name: string);
243+
greet(): string;
244+
}
245+
}
246+
}
247+
}
248+
249+
export interface Greeter extends SwiftHeapObject {
250+
greet(): string;
251+
}
252+
```
253+
254+
Using namespaces can be preferable for projects with many global functions, as they help prevent naming collisions. Namespaces also provide intuitive hierarchies for organizing your exported Swift code, and they do not affect the code generated by `@JS` declarations without namespaces.

0 commit comments

Comments
 (0)