From 8f9655335ede0dd1fc33d56894a697193d3520a1 Mon Sep 17 00:00:00 2001 From: Jacopo Marrone Date: Fri, 11 Jul 2025 10:40:19 +0200 Subject: [PATCH 1/3] docs: add example for type-safe `router to contract` client initialization --- .../content/docs/contract-first/router-to-contract.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/content/docs/contract-first/router-to-contract.md b/apps/content/docs/contract-first/router-to-contract.md index 4a86e7e96..4201b9cb4 100644 --- a/apps/content/docs/contract-first/router-to-contract.md +++ b/apps/content/docs/contract-first/router-to-contract.md @@ -49,3 +49,14 @@ However, if you're deriving the contract from a [router](/docs/router), importin url: 'http://localhost:3000/api', }) ``` + + This usage doesn't make the client type-safe, because `as any` bypass any typescript inference, so you can use `as typeof router` if you want better types + + ```ts + import contract from './contract.json' // [!code highlight] + import type { Router } from '../server/router' // Be sure to use "import type" and not "import" here + + const link = new OpenAPILink(contract as Router, { + url: 'http://localhost:3000/api', + }) + ``` From fe8d6dea85571390f20a610a099374afa459ace4 Mon Sep 17 00:00:00 2001 From: Jacopo Marrone Date: Fri, 11 Jul 2025 11:31:53 +0200 Subject: [PATCH 2/3] docs: better english Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- apps/content/docs/contract-first/router-to-contract.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/content/docs/contract-first/router-to-contract.md b/apps/content/docs/contract-first/router-to-contract.md index 4201b9cb4..41e298fcc 100644 --- a/apps/content/docs/contract-first/router-to-contract.md +++ b/apps/content/docs/contract-first/router-to-contract.md @@ -50,7 +50,7 @@ However, if you're deriving the contract from a [router](/docs/router), importin }) ``` - This usage doesn't make the client type-safe, because `as any` bypass any typescript inference, so you can use `as typeof router` if you want better types +This usage doesn't make the client type-safe, because `as any` bypasses TypeScript's type inference. To correctly type the client, cast the imported contract to the type of your server-side router, as shown in the example below. ```ts import contract from './contract.json' // [!code highlight] From 2b81635b51ce6bfd66f4e84110a557a545c79b58 Mon Sep 17 00:00:00 2001 From: unnoq Date: Fri, 11 Jul 2025 16:45:10 +0700 Subject: [PATCH 3/3] fix format + improve --- .../docs/contract-first/router-to-contract.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/apps/content/docs/contract-first/router-to-contract.md b/apps/content/docs/contract-first/router-to-contract.md index 41e298fcc..994e27e4d 100644 --- a/apps/content/docs/contract-first/router-to-contract.md +++ b/apps/content/docs/contract-first/router-to-contract.md @@ -45,18 +45,11 @@ However, if you're deriving the contract from a [router](/docs/router), importin ```ts import contract from './contract.json' // [!code highlight] - const link = new OpenAPILink(contract as any, { + const link = new OpenAPILink(contract as typeof router, { url: 'http://localhost:3000/api', }) ``` - -This usage doesn't make the client type-safe, because `as any` bypasses TypeScript's type inference. To correctly type the client, cast the imported contract to the type of your server-side router, as shown in the example below. - ```ts - import contract from './contract.json' // [!code highlight] - import type { Router } from '../server/router' // Be sure to use "import type" and not "import" here - - const link = new OpenAPILink(contract as Router, { - url: 'http://localhost:3000/api', - }) - ``` + ::: warning + Cast `contract` to `typeof router` to ensure type safety, since standard schema types cannot be serialized to JSON so we must manually cast them. + :::