Skip to content

Commit

Permalink
docs: TypeScript practices
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Apr 3, 2024
1 parent b3c6c8b commit 9372618
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 21 deletions.
13 changes: 4 additions & 9 deletions docs/typescript.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
# usage of TypeScript

Our use of TypeScript has to accomodate both .js development in agoric-sdk (which cannot import types) and .ts development of consumers of agoric-sdk packages (which can import types). For .js development, we want ambient (global) types so that we don't have to precede each type reference by an import. For .ts development, we want exports from modules so we don't pollute a global namespace.

This means we need two definition files. We could keep those both in SCM, but that would cause more confusion and risk them getting out of sync. We could have one be defined in terms of the other, but since there is no way to reexport to global namespace, it would have to be a secondary definition in the primary. This would typecheck because TS is structurally typed, but the secondary would lose all the documentation on the types.

So our best solution is to have one source of truth for the types and auto-generate for one case from the other. We've chosen to have the ambient types as the source of truth so the SDK development can use them. The SDK consumption can have a build step during packaging, and that's when we make the exported (non-ambient) types.
Our use of TypeScript has to accomodate both .js development in agoric-sdk (which could not import types until TS 5.5) and .ts development of consumers of agoric-sdk packages (which could always import types). For .js development, we have many ambient (global) types so that we don't have to precede each type reference by an import. For .ts development, we want exports from modules so we don't pollute a global namespace. We are slowly transitioning away from ambient types.

## Best practices

- `src/types-ambient.js` defines types of the package
- `src/types.d.ts` is built automatically from types-ambient
- `prepack` copies types-ambient.js to types.js and appends 'export {};' to turn it into a module, then builds
- `postpack` deletes the new types.js and .d.ts files
- package entrypoint(s) exports explicit types
- for packages upon which other packages expect ambient types:
- `exported.d.ts` exports the explicit types and ambient re-exports

## Generating API docs

Expand Down
6 changes: 1 addition & 5 deletions packages/ERTP/exported.d.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
/* eslint-disable -- doesn't understand .d.ts */
/**
* @file re-export types into global namespace, for consumers that expect these
* to be ambient
*/

// export everything
export * from './src/types.js';

// XXX re-export types into global namespace, for consumers that expect these to
// be ambient. Why the _ prefix? Because without it TS gets confused between the
// import and export symbols. h/t https://stackoverflow.com/a/66588974
// Note one big downside vs ambients is that these types will appear to be on `globalThis`.
// UNTIL https://github.com/Agoric/agoric-sdk/issues/6512
import {
Amount as _Amount,
Brand as _Brand,
Expand Down
6 changes: 4 additions & 2 deletions packages/ERTP/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
"maxNodeModuleJsDepth": 1,
},
"include": [
// omit exported.js because 1) it's empty and would overwrite exported.d.ts
// and 2) because it's only for consumption in other packages
// omit exported.js because 1) it need not be included in the typecheck of
// this package because it's only consumed by other packages and 2)
// including it causes the empty exported.js to overwrite the manual
// exported.d.ts (which doesn't need any building)
"src/**/*.js",
"src/**/*.ts",
"test"
Expand Down
7 changes: 2 additions & 5 deletions packages/store/exported.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
/* eslint-disable -- doesn't understand .d.ts */
/**
* @file re-export types into global namespace, for consumers that expect these
* to be ambient
*/
// export everything

export * from './src/types.js';

// XXX re-export types into global namespace, for consumers that expect these to
// be ambient. Why the _ prefix? Because without it TS gets confused between the
// import and export symbols. h/t https://stackoverflow.com/a/66588974
// Note one big downside vs ambients is that these types will appear to be on `globalThis`.
// UNTIL https://github.com/Agoric/agoric-sdk/issues/6512
import {
LegacyMap as _LegacyMap,
LegacyWeakMap as _LegacyWeakMap,
Expand Down

0 comments on commit 9372618

Please sign in to comment.