在 .d.ts 文件中无法识别 TypeScript 接口

TypeScript interface not recognized when in a .d.ts file

我们有一个文件包含 tscvscode 无法识别的接口。

src/sap-truck-roster/resolver/RosterResolver.ts:40:17 - error TS2304: Cannot find name 'Context'.

// src\shared\types\Context.d.ts
import { Roster } from '@sap-truck-roster/entity/Roster'
import { Account } from '@it-portal/entity/Account'

 interface Context {
  user: Account
  dataSources: {
    sapRosterApi: Roster
  }
}

显然我们需要使用选项 typeRoots in tsconfig as suggested here。但出于某种原因,接口 Context 仍然无法识别。我们在这里缺少什么?

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@environment": ["src/environment"],
      "@utils/*": ["src/utils/*"]
    },
    "typeRoots": ["./node_modules/@types", "./src/shared/types/**/*.d.ts"],
    "rootDir": "./src",
    "outDir": "./dist",
    "target": "es6",
  },
  "exclude": ["node_modules"],
  "include": ["./src/**/*.tsx", "./src/**/*.ts", "./src/**/*.d.ts"]
}

使用界面:

import { Resolver, Arg, Query, Ctx, Field, ObjectType, createUnionType } from 'type-graphql'
import { Roster } from '@sap-truck-roster/entity/Roster'
import { plainToClass } from 'class-transformer'

@Resolver()
export class RosterResolver {
  @Query(() => RosterQueryResultUnion)
  async roster(
    @Ctx() ctx: Context,   // use Context without import
    @Arg('date', () => String) date: string
  ): Promise<typeof RosterQueryResultUnion> {
    const response = await ctx.dataSources.sapRosterApi.getRoster(date)

    if (response.returnCode === 'OK') {
      return plainToClass(RosterArray, {
        data: response.data,
      })
    }
    return plainToClass(ApiError, {
      code: response.returnCode,
      message: response.errorMessage,
    })
  }
}

You can achieve this using the module declaration.

declare module SomeName {
    interface Context {
        user: Account
        dataSources: {
          sapRosterApi: Roster
        }
    }
}

现在可以直接这样写了

const ctx: SomeName.Context = {} // without importing anything

更新tsconfig.json
"typeRoots": ["./node_modules/@types", "./src/shared/types/**/*.d.ts"],

"typeRoots": ["./node_modules/@types", "./src/shared/types"],

这一定行得通。如果没有请告诉我。

Codesandbox:https://codesandbox.io/s/ecstatic-tdd-tb11c?file=/src/App.tsx

不放置导出会阻止它被 TS 发现。

.d.ts 文件旨在声明或扩充 namespaces/modules,同时禁止任何其他 TS 操作,因为它们是纯声明文件。

它们并不是要避免使用 import/export。

如果你想全局声明一个接口,你应该通过augmenting the global module

你的情况是

declare global {
  interface Context {
    user: Account
    dataSources: {
      sapRosterApi: Roster
    }
  }
}

但我强烈反对,以后可能会很痛苦

对于您来说,最好创建一个普通的 .ts 文件并导出界面,然后将其导入其他地方。 如果仍然无效,请检查 tsconfig 路径是否配置正确或切换为使用相对导入路径。

乱用 typeRoots 选项通常还会禁用 @types/* 包自动发现并导致相当不可调试的问题。

如果类型或接口位于 .d.ts 文件 中并且当您不从该文件中的任何模块导入任何类型时,您只能在不导入的情况下使用该类型或接口。d.ts 文件.