2

We have a file containing an interface that is not recognized by tsc or by vscode.

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
  }
}

Apparently we need to use the option typeRoots in tsconfig as suggested here. But for one reason or another the interface Context is still not recognized. What are we missing here?

{
  "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"]
}

Using the interface:

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,
    })
  }
}
4
  • Why it isn't exported? Commented Nov 17, 2020 at 9:59
  • When using export and import it works fine. But the goal of using .d.ts files is that this is no longer required and the interface is in the global scope. Commented Nov 17, 2020 at 10:21
  • Can you show how exactly you want to access this interface? Commented Nov 17, 2020 at 10:36
  • Sure thing, updated OP Commented Nov 17, 2020 at 10:40

3 Answers 3

3

Not putting an export prevents it from being discoverable by TS.

.d.ts files are meant to declare or augment namespaces/modules, while banning any other TS operation as they are pure declaration files.

They aren't meant to avoid usage of import/export.

If you want to declare an interface globally, you should do so by augmenting the global module

In your case it would be

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

But I strongly advise against it, it could be a pain in the ass for you in the future

For you it's better to create a normal .ts file and export the interface, then import it somewhere else. If that still doesn't work, check out if tsconfig paths are configured correctly or switch to use relative import paths.

Messing with typeRoots options usually also disable @types/* packages automatic discovery and cause pretty undebuggable problems.

Sign up to request clarification or add additional context in comments.

Comments

3

You only can use the type or interface without importing it if it's in a .d.ts file and when you are not importing any type from any module in that .d.ts file.

Comments

0

You can achieve this using the module declaration.

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

Now you can directly write it like this.

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

Update tsconfig.json from

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

to

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

This must work. Let me know if didn't.

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

3 Comments

This seems like the sensible thing to do, but when I try it I get error TS2503: Cannot find namespace 'SomeName'.
Same issue after updating tsconfig with your suggestion. Even tired adding export as suggested here, no luck.
It must work. Check code sandbox URL. It has only a lint problem, the code is working fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.