#Why would I want to use `namespace` or `module` over just putting data in seperate files?

150 messages · Page 1 of 1 (latest)

worn flare
#

I am currently learning, or at least trying to learn about, namespaces and modules in TypeScript. I have only one question: what the hell? Why would I ever declare a namespace or module instead of just putting data I need to share in a seperate file and just importing that? Is this just something from the past that refuses to die, or is there actually an advantage over putting data in a seperate file?

hallow token
#

i'd say it's mostly a relic (typescript came into being before ES modules were fully specified, and even after they were specified it took a long time for them to be widely supported). some people like being able to group things within files, but i'd generally try to avoid that

worn flare
#

I am currently trying to understand a 300+ file codebase that uses them here and there and they just break my mind

hallow token
#

conceptually they aren't too complicated; just think of them as an inlined file. what breaks your mind about them?

worn flare
#

How you share them across files, and also why you even want to use them

hallow token
#

you can export/import them just like an object/class. the only magical thing about them is that they can contain types as well as values

worn flare
#

so a file withing a file?

#

code within code?

hallow token
#

if you look at the emit they literally compile down to an object (albeit one created in a funky way for scoping reasons)

hallow token
#

classes, functions, etc are all "code within code"

worn flare
#

lets keep it at file within a file

#

classes are blueprints, functions is code itself

hallow token
#

you can sorta analogize namespaces to classes with all-static methods. or just objects with unusual initialization syntax

#

that might be easier than the "file within a file" analogy

worn flare
#

how is this allowed

declare module "*.replacements" {
  const content: {
    file: string;
    filename: string;
  };
  export default content;
}

but this isnt

declare module "thisisamodule.ts" {
  const thing: {
    six: 6;
    text: string;
  };

  export default thing;
}
hallow token
#

oh that's a totally different thing

#

declare module is for declaring type definitions for javascript modules

worn flare
#

javascript modules?

hallow token
#

the things you import from, is all i mean

worn flare
#

oh aha

#

so a type definition is just the javascript version of making a type?

#

oh wait I get it now

hallow token
worn flare
#

the file extension has to be .d.ts in order for declare module to work?

worn flare
#

ooooh

#

wait

#

I do

declare module "thisisamodule.ts" {
  const thing: {
    six: 6;
    text: string;
  };

  export default thing;
}
``` in a `.d.ts` file so I can use types in `.js` files?
hallow token
worn flare
#

Deno certainly shut up when I changed it

hallow token
#

pretty sure you can declare them in .ts files too (though i'd complain if i saw that in a pull request)

hallow token
worn flare
#

but how do I use types in javascript, isnt that what typescript was invented for?

hallow token
hallow token
#

that's what this is for

worn flare
#

yeah I figured

#

but then how do I use the things in a module in javascript?

hallow token
#

whenever you see the keyword declare (not just declare module, but declare ANYTHING) it means "hey typescript compiler, i know there is going to be some existing code at runtime satisfying these types"

#

like all of the built-in stuff (Date, Math, etc) is defined via declare stuff

#

the d in d.ts is also short for "declaration", meaning the same thing

worn flare
#

two questions

#

first

#

wait

#

is this related to the satisfy keyword I saw yesterday for the first time ever

hallow token
#

not really

#

i mean they're related in that they are both doing things with types, but that's true for everything in typescript

worn flare
#

okay then three questions

#

first

#

how do you tell the typescript compiler that some variable is satisfying a type in javascript (in typescript its trivial)

#

Second: how do I make a completely global variable / class myself?

#

third: then what is the satisfies keyword used for?

hallow token
hallow token
worn flare
hallow token
#

ah okay

worn flare
#

oooh right

hallow token
#

but also: don't do that (unless you have a very good reason)

#

what's your use case?

worn flare
#

nothing yet, just wanting to know in case I encounter it in the wild later on

#

wait how do I do it in typescript, my lsp doesn't say that thing is defined

hallow token
#

you need to import thing. since it's a default export i think you can write import thing from "thisisamodule"

#

(but also you shouldn't write code like this except for interoperability with non-typescript code. just use normal typescript stuff otherwise)

worn flare
#

oh right

worn flare
#

that is how I feel about this entire thing with namespaces and modules and the declare keyword

hallow token
#

that's the right feeling IMO

#

so here's some history that might help avoid confusion:

  1. the module keyword originally meant what namespace means today
  2. since module may end up being a valid JS keyword (as in the TC39 proposal i linked to above), typescript added namespace and deprecated module (i think this meaning only became fully unsupported in the latest version of typescript)
  3. declare module is its own thing, still valid for what we've been discussing here
#

so basically if you see declare module it means "there's some JS code somewhere i am describing". if you see namespace it's what i originally was talking about (weird syntax for an object + types)

#

but IMO if you are just authoring your own typescript code you shouldn't use either declare module or namespace

worn flare
#

what if I see declare namespace

hallow token
#

declare generally means "i'm just talking about the type of a value i promise will exist when you go to run the code"

#

so it's like declare const x: string or declare class Foo {}, but for a namespace

worn flare
#

I also saw typeof namespaceName today which made me really mad, like why would you ever need that

hallow token
worn flare
#

you keep saying "a type of a value" but I can also just put regular data in a declare module?

worn flare
#

the namespace is valid everywhere, its global data

hallow token
worn flare
#

wait let me grab the exampe

hallow token
#

const x = { /* stuff */ } and namespace x { /* stuff */ } aren't much different at runtime

hallow token
worn flare
#

static is persistant across all instaces of a class, instatic is not

#
function mapFactory(api: google.maps) {
    return new api.Map();
}

Why would you pass api as a parameter, cant you just do:

function mapFactory() {
    return new google.maps.api.Map();
}
hallow token
#

(unless there also happens to be a value of that name)

worn flare
#

let me send the post where I based this on

hallow token
#

but also maybe you want to allow more than once instance of the API object to exist at the same time ¯_(ツ)_/¯

worn flare
#

this

#

last time I checked you cant have a class definition on a type

hallow token
#

☝️ that's alluding to "you want to allow more than once instance of the API object to exist at the same time"

worn flare
#

but in any other case this would be unnecessary right? so I am still partially correct :)

#

okay but now the second questipn

#

how do I make namespaces global

hallow token
#

my first-order snide-but-serious answer is: "don't" 😄

#

i can explain how if you're certain you really need to do that

#

but generally in modern javascript/typescript you should avoid global stuff

worn flare
#

i am seeing that a namespace is accessed in a file without it importing it

#

said namespace is defined in a package

#

with declare namespace

hallow token
#

do you know the difference between a "script" (sometimes called "ambient") and a "module"?

worn flare
#

I do not

hallow token
#

how long have you been doing web stuff? just wondering what i can gesture at to explain this stuff

#

like, have you written <script> tags yourself?

worn flare
#

I have done almost exclusively discord bots and other stuff that does not involve frontend things in anyway

#

well except for svelte(kit), ubut that is a different story

hallow token
#

okay no worries

#

so typescript (under certain module settings) can treat a .ts file in one of two ways depending on what it contains: either as a "script" or a "module"

#

oh sorry phone call, be back in a bit

worn flare
#

I published my own JSR package for backend routing, but i can count the amount of script tags I have made on my hands 😅

worn flare
hallow token
#

alright i'm back

hallow token
worn flare
#

I am also back

worn flare
#

ill try

#

omg typescripts biggest weakness is javascript

hallow token
#

dude it's like 5 sentences (disregarding the blue box talking about ESM vs CJS, which is mostly irrelevant)

#

i'm not saying to read the whole page (though it does have lots of good nuggets/history), just that one section i linked to

worn flare
worn flare
#

I wish someone made a new internet with a language that isn't bad. No matter how good your framework / wrapper language for web purposes is, the bottleneck will always be javascripts bad design.

hallow token
#

people thought webassembly would be this. and maybe some day it will, but that day is not today

worn flare
#

Some time ago a informatics (coding) teacher asked me and a bunch of other students to do a project together because we had coding as a hobby, and my proposal was a copy of the internet with rust instead of javascript and typst (a markup language similar to latex) instead of html, but my proposal ultimately wasnt chosen

#

Personally, I think that if you remove all the javascript quirkyness out of typescript (like the loosely equals operator) and maybe some other cleanups (like how interface and class are pretty much identical) then I think you have the perfect language for the web

#

And maybe some rust components like implenting traits

hallow token
#

i think you're just being casual but since it's a pet peeve of mine: you mean "web", not "internet". it doesn't sound like you want to reinvent IP or TCP/UDP/QUIC, etc (maybe not even HTTP), just the standard languages used by browsers

#

rust doesn't quite make sense to me here though. you need an interpreted language or at least machine-agnostic bytecode (like webassembly)

#

(as much as i like rust)

worn flare
#

No i think web is pretty much it, the idea was to have two computers not connected to the internet talk to each other

worn flare
hallow token
#

oh yeah then i'm on board. one advantage JS and other scripting languages have is that they can start being executed while code is still being downloaded, and globally-relevant things like traits can make that tricky, but i'm sure that problem could be worked around

worn flare
#

a friend of mine also suggested that such a language has to be compiled, but I wasn't so sure of that

#

I hope that some day javascript could die and be replaced by something better

#

also before we go back to modules I also had a name for that language: SuperScript

#

in math, the place of an exponent is called a superscript because its a script (something that is written) super (above) an expression

#

Anyway

#

so where were we