我的处境有点奇怪。在过去的两周里,我一直在尝试调试为什么我在 monorepo 内的项目之间丢失类型。我的后端公开了我的客户端使用的类型,但由于某种原因,某些类型无法理解并成为any
。这使得我有一段时间无法在这个项目上开发任何东西。我根据该问题制作了一个示例存储库以进一步展示它。 https://github.com/Nikola-Milovic/monorepo-trpc-issue
该项目是用Yarn Workspaces
它的结构如下
-
apps/site
,导入 tRPC 的 NextJS 客户端AppRouter
-
apps/backend
,暴露的 Express 后端AppRouter
-
apps/config
,这是基础tsconfig
整个项目中都使用了s
-
packages/frontend-shared
,对于这个问题来说并不重要,共享 UI 组件
问题可以在客户端内部找到in the apps/site/src/lib/ApiProvider.ts https://github.com/Nikola-Milovic/monorepo-trpc-issue/blob/master/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 = {}
类型为tRPC
方法输出被推断为any
由于某种原因,const a
类型是别名Profile
但即使我添加不存在的字段,类型检查器也不会抱怨。
The const b
and const t
打字正确
就打字稿配置而言,我的设置非常标准,我用这个底座tsconfig https://github.com/Nikola-Milovic/monorepo-trpc-issue/blob/master/packages/tsconfig/base.json它设置了一些合理的默认值,例如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"]
}
我尝试过修改 tsconfigs,完全重做它们,尝试删除路径别名,清理纱线缓存,尝试使用从前端到后端的项目引用,但我一直遇到同样的问题
调试起来非常困难,因为这里只发生了打字稿魔法,没有错误或任何我可以研究的东西,我遵循了tRPC
设置指南,但由于某种原因,某些设置或导致类型被破坏。
我 90% 确定问题实际上不是tsconfig
因为我也复制了其他人的整个设置,但它仍然导致相同的类型推断。我不知道还有什么会以这种方式影响打字稿,我最后的手段似乎是将 API 层放入一个包中,并在我的包中直接导入它,但这很糟糕,并且需要相当多的重构,而我100% 确定我当前的设置确实可以工作