【发布时间】:2023-02-01 20:48:56
【问题描述】:
我的处境有点奇怪。在过去的 2 周里,我一直在尝试调试为什么我在 monorepo 中的项目之间丢失类型。我的后端公开了我的客户使用的类型,但出于某种原因,某些类型无法通过并成为 any。这让我有一段时间无法在这个项目上开发任何东西。 I made a sample repo out of the issue to further showcase it.
该项目是用Yarn Workspaces构建的,其结构如下
-
apps/site,NextJS 客户端导入 tRPCAppRouter -
apps/backend,暴露AppRouter的 express 后端 -
apps/config,这里是整个项目中使用的基础tsconfigs -
packages/frontend-shared,这个问题不重要,共享UI组件
问题可以在客户端里面找到in the 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 的别名,但即使我添加了不存在的字段,类型检查器也不会抱怨。
const b 和 const t 的输入正确
就打字稿配置而言,我的设置非常标准,I use this base 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"]
}
我尝试修改 tsconfigs,完全重做它们,尝试删除路径别名,清理纱线缓存,尝试使用从前端到后端的项目引用,但我一直遇到同样的问题
很难调试为什么因为这里只发生了打字稿魔术,没有错误或任何我可以查看的东西,我遵循了tRPC设置指南但由于某些原因,某些设置或导致类型被破坏。
我 90% 确定问题实际上不是 tsconfig 的问题,因为我还从其他人那里复制了整个设置,但它仍然导致相同的类型推断。我不知道还有什么会以这种方式影响打字稿,我的最后一招似乎是将 API 层制作成一个包并直接将其导入到我的包中,但这很老套,需要进行大量重构,而我100% 确定我当前的设置确实有效
【问题讨论】:
-
我遇到了同样的问题,所以我设置了最小的工作示例并开始添加代码直到类型产生任何类型。原来这是因为我在我的一种自定义类型中使用了
infer。 -
遇到了类似的问题。我使用路径别名来引用我的后端类型。问题是我也在后端使用路径别名。一旦我在后端使用相对路径,前端就会正确获取类型。
-
@oae 哦,这可能是问题所在,我通过直接在 /dist 中导入转译后的代码来解决这个问题。这有点难看,但它让我摆脱了这 1 个月的车辙
标签: typescript next.js yarn-workspaces zod trpc.io