diff --git a/CHANGELOG.md b/CHANGELOG.md index 5010ea4f11..a706b1a7fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -88,6 +88,10 @@ It is now possible to set the http adapter's log level in dfx.json or in network By default, a log level of "error" is used, in order to keep the output of a first-time `dfx start` minimal. Change it to "debug" for more verbose logging. +### fix(typescript): add index.d.ts file for type safety when importing generated declarations + +Adds an index.d.ts file to the generated declarations, allowing for better type safety in TypeScript projects. + ### chore: reduce verbosity of dfx start `dfx start` produces a lot of log output that is at best irrelevant for most users. diff --git a/docs/cli-reference/dfx-generate.md b/docs/cli-reference/dfx-generate.md index 6bbf8cc86c..bc0463be8f 100644 --- a/docs/cli-reference/dfx-generate.md +++ b/docs/cli-reference/dfx-generate.md @@ -43,12 +43,12 @@ The behavior of `dfx generate` is controlled by the `dfx.json` configuration fil Outputs from `dfx generate`: -| Language | File | -|------------------|-----------------------------------------| -| `JavaScript(js)` | `index.js` and `.did.js` | -| `TypeScript(ts)` | `.did.ts` | -| `Candid(did)` | `.did` | -| `Motoko(mo)` | `.mo` | +| Language | File | +|------------------|------------------------------------------| +| `JavaScript(js)` | `index.js` and `.did.js` | +| `TypeScript(ts)` | `index.d.ts` and `.did.ts`| +| `Candid(did)` | `.did` | +| `Motoko(mo)` | `.mo` | ## Examples diff --git a/e2e/tests-dfx/generate.bash b/e2e/tests-dfx/generate.bash new file mode 100755 index 0000000000..33a1ffcc57 --- /dev/null +++ b/e2e/tests-dfx/generate.bash @@ -0,0 +1,31 @@ +#!/usr/bin/env bats + +load ../utils/_ + +setup() { + standard_setup + + dfx_new hello +} + +teardown() { + dfx_stop + + standard_teardown +} + +@test "dfx generate creates files" { + dfx_start + dfx canister create --all + dfx build + dfx canister install --all + + dfx --version + dfx generate + + assert_file_exists "src/declarations/hello_backend/hello_backend.did" + assert_file_exists "src/declarations/hello_backend/hello_backend.did.js" + assert_file_exists "src/declarations/hello_backend/hello_backend.did.d.ts" + assert_file_exists "src/declarations/hello_backend/index.js" + assert_file_exists "src/declarations/hello_backend/index.d.ts" +} diff --git a/src/dfx/assets/language_bindings/index.d.ts.hbs b/src/dfx/assets/language_bindings/index.d.ts.hbs new file mode 100644 index 0000000000..67b9b56b57 --- /dev/null +++ b/src/dfx/assets/language_bindings/index.d.ts.hbs @@ -0,0 +1,16 @@ +import { ActorSubclass, HttpAgentOptions, ActorConfig } from '@dfinity/agent'; +import { Principal } from '@dfinity/principal'; + +import { _SERVICE } from './{{canister_name}}.did'; + +export declare interface CreateActorOptions { + agentOptions?: HttpAgentOptions; + actorOptions?: ActorConfig; +} + +export declare const createActor: ( + canisterId: string | Principal, + options: CreateActorOptions +) => ActorSubclass<_SERVICE>; + +export declare const {{canister_name}}: ActorSubclass<_SERVICE>; diff --git a/src/dfx/src/lib/models/canister.rs b/src/dfx/src/lib/models/canister.rs index c58fedd401..80a1f9bfb5 100644 --- a/src/dfx/src/lib/models/canister.rs +++ b/src/dfx/src/lib/models/canister.rs @@ -596,6 +596,7 @@ fn build_canister_js(canister_id: &CanisterId, canister_info: &CanisterInfo) -> } // skip "index.js.hbs" => {} + "index.d.ts.hbs" => {} _ => unreachable!(), } }