Nik*_*vic 12 typescript next.js yarn-workspaces zod trpc.io
我的处境有点奇怪。在过去的两周里,我一直在尝试调试为什么我在 monorepo 内的项目之间丢失类型。我的后端公开了我的客户端使用的类型,但由于某种原因,某些类型只是无法传播并成为any. 这使得我有一段时间无法在这个项目上开发任何东西。我根据该问题制作了一个示例存储库以进一步展示它。
该项目的构建Yarn Workspaces和结构如下
apps/site,导入 tRPC 的 NextJS 客户端AppRouterapps/backend,暴露的 Express 后端AppRouterapps/config,这是tsconfig整个项目中使用的基础packages/frontend-shared,对于这个问题来说并不重要,共享 UI 组件问题可以在客户端内部找到apps/site/src/lib/ApiProvider.ts
// The type is imported directly from backend, here we use type alias to make it cleaner
import type { AppRouter, EmailType, ProfileType, Test } from "@company/backend/trpc";
export type { AppRouter } from "@company/backend/trpc";
import { inferProcedureOutput } from "@trpc/server";
// The type is inferred to any
// Also if you hover over the app router, the context is also any
type loginOutputType = inferProcedureOutput<AppRouter["user"]["login"]>;
//Profile type doesn't have test field but it lets me set it
const a: ProfileType = {};
a.test = false;
//Same as well here, but it errors out as it should
const b: EmailType = {};
b.test = false;
//
const t: Test = {}
Run Code Online (Sandbox Code Playgroud)
由于某种原因tRPC推断方法输出的类型,该类型是别名,但即使我添加不存在的字段,类型检查器也不会抱怨。anyconst aProfile
和const b的const t输入正确
就打字稿配置而言,我的设置非常标准,我使用这个基础tsconfig设置了一些合理的默认值strict,所有其他配置都继承自它
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Default",
"compilerOptions": {
"composite": false,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"inlineSources": false,
"isolatedModules": true,
"moduleResolution": "node",
"preserveWatchOutput": true,
"skipLibCheck": true,
"noUncheckedIndexedAccess": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": false
},
"exclude": ["node_modules"]
}
Run Code Online (Sandbox Code Playgroud)
我尝试修改 tsconfigs,完全重做它们,尝试删除路径别名,清理纱线缓存,尝试使用从前端到后端的项目引用,但我一直遇到同样的问题
调试起来非常困难,因为这里只发生了打字稿魔法,没有错误或任何我可以研究的东西,我遵循了设置指南,tRPC但由于某种原因,某些设置或导致类型被破坏。
我 90% 确信问题实际上不是 的,tsconfig因为我还复制了其他人的整个设置,但它仍然导致相同的类型推断。我不知道还有什么会以这种方式影响打字稿,我最后的手段似乎是将 API 层放入一个包中,并在我的包中直接导入它,但这很糟糕,需要相当多的重构,而我100% 确定我当前的设置确实可以工作
我有类似的问题。我有一个 monorepo 设置,有 2 个包,一个trpc-backend和mobile-app. 要在前端应用程序上解决此问题,我必须将该references属性添加到我的前端 tsconfig.json 中
{
...
"references": [{ "path": "../trpc-backend" }]
}
Run Code Online (Sandbox Code Playgroud)
执行此操作时,您将收到一条 ts 警告,指出引用的项目必须设置composite为 true。要解决此问题,请转到后端代码并在compilerOptions
so...下添加复合属性
{
...
"compilerOptions": {
...
"composite": true,
}
}
Run Code Online (Sandbox Code Playgroud)
你就完成了
只是归功于@oae 的回答/评论,它为我解决了这个问题
问题是我也在后端使用路径别名。一旦我在后端使用相对路径,前端就会正确获取类型
编辑:但我认为有一个更优雅的解决方案,即将别名导入转换为相关导入后直接发出js输出文件,这可以通过https://github.com/justkey007/tsc-alias来实现,例如:
{
...
"scripts": {
"build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1900 次 |
| 最近记录: |