-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: generate types for
extern
declarations (#5967)
Closes #5868 (except the static part, but that's not critical for the use-case) Compiling a wing project will now generate .d.ts files for the contract between wing and extern files. These .d.ts files are fully self-contained. The code for this looks similar to existing dtsification code, but there are couple important distinctions that made it feel useful to separate it: 1. The new code only access to type information rather than the original ASTs 2. The new code is intentionally generating types in the same file as needed instead of producing references Misc: - No longer emit any files if any errors occur during compiliation - Internally change extern to use Utf8PathBuff - Converted some `examples` externs into typescript (I would love to do the rest, but need #3013) Note that this may be a breaking change: extern types must be consistent. So in one class you refer to an extern as returning a `str` and in another it returns a Json, that will now be a compiler error. *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*.
- Loading branch information
1 parent
a361e81
commit 75b30ad
Showing
34 changed files
with
926 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,58 @@ | ||
--- | ||
title: Using JavaScript | ||
title: Using JavaScript/TypeScript | ||
id: using-javascript | ||
keywords: [Wing example] | ||
keywords: [example, javascript, extern, typescript, js, ts] | ||
--- | ||
|
||
Calling a Javascript function from Wing requires two steps. | ||
Calling a Javascript function from Wing requires two steps. | ||
|
||
First, export the function from Javascript. | ||
|
||
This examples exports `isValidUrl` from a file named`url_utils.js`: | ||
1. Create a .js file that exports some functions | ||
|
||
```js | ||
exports.isValidUrl = function(url) { | ||
try { | ||
new URL(url); | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
// util.js | ||
|
||
exports.isValidUrl = function (url) { | ||
return URL.canParse(url); | ||
}; | ||
``` | ||
|
||
### Preflight function | ||
|
||
To call this in preflight code, define the function as an `extern` in a class. | ||
|
||
**Note:** Extern functions must be `static.` | ||
In preflight, this file must be a CommonJS module written in Javascript. Inflight, it may be CJS/ESM and either JavaScript or TypeScript. | ||
|
||
If you want to use the function outside of the class, be sure to declare it as `pub`. | ||
2. Use the `extern` keyword in a class to expose the function to Wing. Note that this must be `static`. It may also be `inflight` | ||
|
||
```ts | ||
class JsExample { | ||
// preflight static | ||
pub extern "./url_utils.js" static isValidUrl(url: str): bool; | ||
```ts | ||
class JsExample { | ||
pub extern "./util.js" static isValidUrl(url: str): bool; | ||
} | ||
|
||
assert(JsExample.isValidUrl("http://www.google.com")); | ||
assert(!JsExample.isValidUrl("X?Y")); | ||
``` | ||
|
||
### Inflight | ||
### Type-safe `extern` | ||
|
||
To call the function inflight, add the `inflight` modifier. | ||
Running `wing compile` will generate a corresponding `.d.ts` file for each `extern`. This file can be imported into the extern file itself to ensure the extern is type-safe. Either your IDE or a separate usage of the TypeScript compiler can provide type-checking. | ||
|
||
```ts | ||
class JsExample { | ||
// inflight static method | ||
extern "./url_utils.js" static inflight isValidUrl(url: str): bool; | ||
} | ||
// util.ts | ||
import type extern from "./util.extern"; | ||
|
||
test "main" { | ||
assert(JsExample.isValidUrl("http://www.google.com")); | ||
assert(!JsExample.isValidUrl("X?Y")); | ||
} | ||
export const isValidUrl: extern["isValidUrl"] = (url) => { | ||
// url is known to be a string and that we must return a boolean | ||
return URL.canParse(url); | ||
}; | ||
``` | ||
|
||
The .d.ts file can also be used in JavaScript via JSDoc comments and can even be applied at a module export level. | ||
|
||
```js | ||
// util.js | ||
/** @type {import("./util.extern").default} */ | ||
module.exports = { | ||
isValidUrl: (url) => { | ||
return URL.canParse(url); | ||
}, | ||
}; | ||
``` | ||
|
||
Coming Soon: The ability to use resources inside an `inflight extern`. See [this issue](https://github.com/winglang/wing/issues/76) for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default interface extern { | ||
logging: () => Promise<void>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export default interface extern { | ||
createServer: (body: string) => Promise<IHttpServer$Inflight>, | ||
} | ||
export interface Address { | ||
readonly port: number; | ||
} | ||
export interface IHttpServer$Inflight { | ||
readonly address: () => Promise<Address>; | ||
readonly close: () => Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default interface extern { | ||
platform: () => Promise<string>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default interface extern { | ||
validateUUIDv4: (uuidv4: string) => Promise<boolean>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export default interface extern { | ||
_getItem: (tableName: string, key: Readonly<any>) => Promise<Readonly<any>>, | ||
_putItem: (tableName: string, item: Readonly<any>) => Promise<void>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.