#Global import not working when utilizing the declare global {} in typescript declarations files

62 messages · Page 1 of 1 (latest)

queen cradle
#

Take a look at this file

src/@types/user.d.ts

declare global {
export interface IUser {
name: string;
age: number;
}
}

And in this file

game/user/user.ts

const object: IUser => {}

I get an error saying

Cannot find name 'IUser'.

How come it isn't working? I added the declare global {} around the interface. It should work no? I should be allowed to use it anywhere in my code without having to import it in.

wraith fractal
#

Are you using ts-node? If not, what does your tsconfig.json look like? Also you might try without declare global

#

(Also, I really recommend not doing this)

queen cradle
#

I am using Create React App + TypeScript
npx create-react-app my-app --template typescript

#

My tsconfig.json looks like this
{ "compilerOptions": { "target": "es5", "lib": [ "dom", "dom.iterable", "esnext" ], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx" }, "include": [ "src" ] }

#

Also can you please elaborate on why you REALLY recommend not doing this? Is it because it pollutes the global namespace? Because if so I think for my current project its not too clunky to where it will be error prone.

fathom notch
#
  1. You should put global types in a .ts file a .d.ts file, because with skipLibCheck: true TS will not type check .d.ts files.
#
  1. Using a @types folder is a bit odd, as that is a special nom organisation for types packages. I don't think it should break anything, just a bit odd to see that in particular.
#
  1. Your module / moduleResolution settings don't look correct. moduleResolution needs to be Node16 at least. Possibly module should be Node16 too, but I'm not sure / might not matter here.
#
  1. A .d.ts is global already (unless it has imports or exports) so declare global isn't needed. Wild guess, the declare global creates an error, and the error is not shown because of skipLibCheck. I might be wrong, just a guess.
#
  1. Global types aren't really necessary as you can just import them. Personally I don't see a big problem with them, so long as they are type checked. Probably avoid using interfaces in case you accidentally merged into another global interface that could be confusing.
queen cradle
queen cradle
queen cradle
fathom notch
queen cradle
#

No I'm talking about the folder that holds all the type information

Currently I have a folder called "@types"

Where inside of it I have .d.ts files like "user.d.ts"

You said its weird that I named the folder "@types" maybe I read it wrong?

fathom notch
queen cradle
#

Got it

fathom notch
#

As apps get bigger, the risk of conflict and complexity of managing this increases

#

Hence why we use modules and imports/exports to isolate code

queen cradle
fathom notch
#

.d.ts files are types files meant to accompany a .js file. If you write .ts file TS will produce a .js and a .d.ts file.

#

But if you want to declare an external module (a .js file) then it's more natural to write a .d.ts, because that's the .js + .d.ts pairing

#

The technical reason is just.... Because that's how it is. TS just won't accept module declarations in a .ts file

queen cradle
#

Thank you!

#

Last question. I see sometime people add this into their TSX

import {type something} from 'somewhere';

Why do they add the type?

And when do you know where you should add it?

wraith fractal
#

95% of the time it's just a style thing - some people like the clarity of being able to know if an import is a type import or a value import.

queen cradle
#

I'm assuming its for bundle size

#

Because types are only meant for development, to make your life easier

#

No need to have them in the final build you know

wraith fractal
#

It's not a bundle size thing because type imports need to be stripped out at runtime anyway or it blows up

queen cradle
#

Or maybe I'm wrong?

wraith fractal
#

The 5% in the 95% is that 1) there's a few cases where a single-file-at-a-time parser cannot tell if an import is a type import or not

#

e.g.

// Should this be removed?  Impossible to tell just by reading this file
import { Foo } from "./foo";
export { Foo };
#

If you turn on --isolatedModules in tsconfig, it'll warn you about these cases.

#

(Which you do have on)

#

And 2) there are tsconfig settings that change the default behavior in order to require type annotations to remove imports. --verbatimModuleSyntax being the main one.

queen cradle
#

Understood

wraith fractal
#

You might turn on --verbatimModuleSyntax if you need imports to stick around for side-effect reasons, but I don't personally see much value - I also personally don't mark type imports, but that may just be habit.

#

(Either way I'd have VSCode be doing the import and not writing it manually)

queen cradle
#

Gotcha

fathom notch
#

I believe that import type { X } from 'x' will make sure TS only imports types, and the import gets erased during compilation. This is useful if you want to import types from the backend into a frontend app, but make sure you don't import actual API runtime code into your frontend. But I think import { type X } from 'x' leaves the import as import 'x'

#

Retsam might know if that is correct or not

wraith fractal
#

import { type X } from 'x' leaves the import as import 'x'

#

Only if --verbatimModuleSyntax is on

#

If you don't specifically opt into that behavior via vMS, it really is only the --isolatedModules edge cases where the type annotation has any difference.

queen cradle
#

Thank you

#

Appreciate the help

ionic tapirBOT
#
retsam19#0

Preview:```ts
import {type SomeType} from "./foo1"
import type {SomeType2} from "./foo2"
import {SomeType3} from "./foo3"
import {SomeValue} from "./foo4"

console.log(SomeValue)```

wraith fractal
#

^ You can see this in the playground if you look at the ".js" output tab

fathom notch
#

I'll check it when I'm awake

wraith fractal
#

If you turn on --vMS only the import type is erased, if you turn it off, they're all erased except the import that's used as a value.

wraith fractal
#

Types are basically a form of documentation and it's less helpful if you're constantly switching back and forth between two separate sets of files.

fathom notch
#

True

wraith fractal
#

e.g. component props go with the components they describe, types that describe backend objects I'd put with the APIs that fetch and update those objects, etc.

fathom notch
#

I hate switching between files. I've had one project when centrally organised types made sense. That's where I had a server and client sharing a lot of types

fathom notch
fathom notch