next.js 在monorepo项目中丢失Zod和tRPC类型,类型会导致任何

flvtvl50  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(130)

我的情况有点奇怪。在过去的两周里,我一直在调试为什么我在monorepo中的项目之间丢失类型。我的后端公开了我的客户端使用的类型,但由于某些原因,某些类型无法通过并成为any。这使我暂时无法在此项目上开发任何内容。I made a sample repo out of the issue to further showcase it.
该项目使用Yarn Workspaces构建,其结构如下

  • apps/site,导入tRPC AppRouter的NextJS客户端
  • apps/backend,公开AppRouter的快速后端
  • apps/config,以下是整个项目中使用的基本tsconfig
  • 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方法输出的类型被推断为anyconst a类型是Profile的别名,但即使我添加了不存在的字段,类型检查器也没有抱怨。
const bconst t的类型正确
就typescript配置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"]
}

我尝试过修改tsconfig,完全重做,尝试过删除路径别名,清理Yarn缓存,尝试过从前端到后端使用项目引用,但我一直遇到同样的问题
这是非常困难的调试为什么只有 typescript 魔术发生在这里,没有错误或任何种类的东西,我可以看看,我按照tRPC安装指南,但由于某种原因,一些设置或导致类型被打破。
我有90%的把握这个问题实际上不是tsconfig的,因为我也从其他人那里复制了整个设置,它仍然导致了相同的类型推断。我不知道还有什么会影响typescript这样做,我最后的手段似乎是将API层制作成一个包,并使用直接导入到我的包中,但这是hacky,将需要相当多的重构,虽然我100%确定我当前的设置确实应该工作

vyswwuz2

vyswwuz21#

只是相信@oae的回答/评论,它为我解决了这个问题
问题是我在后端也使用了路径别名,一旦我在后端使用了相对路径,前端就能正确地得到类型
编辑:但我认为有一个更优雅的解决方案,那就是在将别名导入转换为相对导入后直接发出js输出文件,这可以通过https://github.com/justkey007/tsc-alias实现,例如:

{
  ...
  "scripts": {
    "build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
   ...

相关问题