#Problem organizing types

59 messages · Page 1 of 1 (latest)

urban ether
#

Hi, I have a namespace issue.
I have a file that is generated and has a number of types and corresponding functions exported from it. I then inport all of the functions and all of the types into a non generated file. Some of the functions I want to override. So I change those functions and export all of the generated functions, minus the old version of the changed ones, plus the new versions of the changed ones.
When I import all of the generated types from the code generated file I get a namespace with all my types in it. Somehow I have to replace the old generated types with the new types I customized and export that as a name space. Otherwise my collection of functions wont match my collection of types.

Please let me know if this makes sense as I can try and expand on it. Basically I need to be able to customize some items that have been code generated and have the types match.

robust karma
#

this is what i imagine based on your description, but i bet i'm missing something:

sand wadiBOT
#
mkantor#0

Preview:```ts
namespace GeneratedFile {
export type A = "a"
export const a = (): A => "a"

export type B = "b"
export const b = (): B => "b"
}

namespace OtherFile {
export type A = "aaa"
export const a = (): A => "aaa"

export type B = GeneratedFile.B
export const b = GeneratedFile.b
...```

urban ether
#

@robust karma Thanks for the response. The problem is, there are a bunch of type/function pairs in "GeneratedFIle". So re exporting them in "OtherFile" is not really practical. Idealy I would like to do something like

import * as Letters from "./GeneratedFile";

namespace OtherFile {
  export type A = "aaa"
  export const a = (): A => "aaa"

   ...Leters
}

Or somethinkg like that, but I'm pretty sure you can't spread a namespace.

robust karma
urban ether
#

Hi, if that works that would be great. That is exactly what I need. What I've been trying is

import * as Letters from "./generated";
export type A = "aaa"
export const a = (): A => "aaa"
export {Letters};

And that did not seem to work.
But I see how what you are saying is different.
I really hope this works!
Thank you!!!

#

So @robust karma I think I need some clarification.
Here let me use the actual terms I'm using. This work is around my custom enums. I have a file where I try to coalesce all of enums, both the generated ones and the overwritten ones, then try to export them as one source.
The idea is, I don't want people to have to import {XYZ} from "./generatedEnums" and import {ABC} from "./customEmums" because ABC still exists in "./generatedEnums" so there's a great chance they will import the wrong one.

#

So what I have is this, let's say this is index.ts

import * as custom from './genCustomization';
import * as genEnums from './generatedEnums/smartEnums';

import type * as Enums from './generatedEnums/smartEnums';

const {
  HomeBelongingType,
  MethodOfContact,
  RelationshipToParty,
  ...rest
} = genEnums;
const enums = { ...rest, ...custom };

export { Enums };
export { enums };

Now obviously I'm not even exporting the new type. But my question is this. When I import enums I want to do import {enums, Enums} from "./path/enums"

#

then I"d do like enums.HomeBelongingType.TV
Now it would also work not to namespace them and just do import {HomeBelongingType} from "./path/enums" if that's possible but I don't know

robust karma
#

Now it would also work not to namespace them and just do import {HomeBelongingType} from "./path/enums" if that's possible but I don't know
yeah, this should work. modules are namespaces, and you can get a direct handle on the entire namespace via the import * as X syntax, or pick and choose individual symbols to import

urban ether
#

But then I don't know how to override the custom enums.

robust karma
urban ether
#

More likely I'm confused :). So in that approach, how do I consume them in another file? Would I do import * as enums from "./other-file"

#

and/or import {HomeBelongingType} from "./other-fle"

robust karma
#

sure. it's just a normal module, nothing special

#

do you always have your modules export a single explicitly-written-out namespace object? if so that's definitely not necessary. like i said, modules already are namespaces

urban ether
#

No, I just found that when I did the above import type * as Enums from "... I got a namespace, and what I wanted was to do
Enums.HomeProperty rather than Enums["HomeProperty"}

robust karma
urban ether
#

sure, sorry.

type MyObject: {
  id: string;
  name: string;
  property: Enums["HomeProperty"];
}

const x = (input: MyObject) => {
  console.log(input.property.TV);
}

I really don't want to do Enums["HomeProperty"]. I want to do the Enums.HomeProperty. Or even better import {HomeProperty} from "./...

robust karma
#

where does Enums come from in this example? if Enums is a namespace which contains a type named HomeProperty then Enums.HomeProperty is how you refer to that type. Enums["HomeProperty"] is referring to the type of the value named HomeProperty

urban ether
#

yes. so I think were getting a bit confused based on some paths I went down a while ago. At one point with however I was organizing the code I had to do the ["..."] version, but then when I started importing * as X I got a namespace and I was able to do it with the dot nomenclature. But then I was married to the namespace. But I think with your suggestions I can just export everything and then import individuals rather than the whole namespace.

robust karma
#

yeah, that ought to work

#

maybe this will help clarify the difference for future reference:

sand wadiBOT
#
mkantor#0

Preview:```ts
// @strict: true

// @filename: a.ts
export type A = "a type"
export const A = "a value" as const

// @filename: b.ts
import * as ANamespace from "./a.js"
type A1 = ANamespace.A
// ^?
type A2 = typeof ANamespace["A"]
// ^?```

urban ether
#

Uh oh. So I dd this

export * from './genCustomization';

export * from './generatedEnums/smartEnums';

and I got "Multiple exports of name 'HomeBelongingType'." error

robust karma
#

hm, maybe you can only shadow exports with local definitions, not across two different re-exports

#

(i think you want them the other way around anyway. your customizations should override the generated ones)

#

would it be problematic to just inline the stuff from ./genCustomization into this file?

urban ether
#

yea I just thought about the order

#

It would I'm afraid. I could import them and export them explicitly. there will be far fewer then the generated ones

robust karma
#

yeah if you can give each one a local name and export that (rather than using export *) i bet that'd work

#

just curious: what's the problem with inlining? that would involve less ongoing maintenance (if you add/remove enums)

urban ether
#

By inlining you mean instead of importing define it right in the file? The issue there is that some of these can be pretty long and the file would be huge

#

I get this error when trying to do it explicitly
Individual declarations in merged declaration 'HomeBelongingType' must be all exported or all local.ts(2395)

robust karma
robust karma
urban ether
#

Well, I"m exporting them all from genCustomization, so that I don't have to update this file ... as much

#

We are using ts 4.9.4

robust karma
# urban ether Well, I"m exporting them all from genCustomization, so that I don't have to upda...

i think there's some miscommunication on this point. you said:

The issue there is that some of these can be pretty long and the file would be huge
and then i said (paraphrased):
it's just the same file with one extra line (export * from './generatedEnums/smartEnums') at the top
from what i was imagining there's either an N-line file and a separate 2-line file, or a single N+1 line file. i probably have the wrong idea though

#

anyway gimme a minute to set up a local repro to make sure i'm not misleading you

urban ether
#

oh. wait. so I could add that export to the genCustomization.ts file. Then all the stuff in genCustomization.ts would be "non local"

robust karma
#

yeah i think that's what i'm saying

urban ether
#

no, I get "Multiple exports of name 'HomeBelongingType"
so genCustomization.ts really just does export { HomeBelongingType } from './HomeBelongingType';

#

with several different files.

robust karma
#

i reproduced locally without problems, then did it again in the bug workbench so i can show you what i mean. i see no errors here:

sand wadiBOT
#
mkantor#0

Preview:```ts
// @strict: true

// @filename: generated-file.ts
export type A = 'a'
export const a = (): A => 'a'
export type B = 'b'
export const b = (): B => 'b'

// @filename: other-file.ts
export * from './generated-file.js'
export type A = 'aaa'
export const a = (): A => 'aaa'
...```

urban ether
#

so then I can do import * as custom from "./genCustomization"

robust karma
urban ether
#

Ah, but that is "inline" right? That would result in the "other-file" being very large

robust karma
#

yeah, see previous message. i didn't realize you wanted one enum per file

urban ether
#

For the custom ones, yes. So, ... sorry, what is the recommended way to do it?

robust karma
#

here's a more elaborate example which separates out more things into their own files:

sand wadiBOT
#
mkantor#0

Preview:```ts
// @strict: true

// @filename: generated-file.ts
export type A = 'a'
export const a = (): A => 'a'
export type B = 'b'
export const b = (): B => 'b'
export type C = 'c'
export const c = (): C => 'c'

// @filename: overridden-a.ts
export type A = 'aaa'
export const a = (): A => 'aaa'
...```

robust karma
#

that does still mean you need to maintain your equivalent of everything.ts as you add more enums, but maybe you think that's worth it to avoid a single large file

#

i guess if you're creating a new file every time you add an enum anyway then remembering to update everything.ts also isn't that big of a deal

urban ether
#

Holly crap. I'm an idiot. I didn't realize that discord was truncating the code. So on some of your suggestions I ddin't see the whole thing. SOrry about that.
That said this last one seems to be great! So I"m getting errors but they are lint errors. I wonder if I can get my ide to show TS errors a different color.
Anyway. I'm giving this a shot. Thank you! I'll write back with results.

robust karma
#

oooh, i was kinda confused about why you kept asking basically the same questions 😅

#

yeah whenever you see that "Playground Link" chrome thing you should click through to the actual playground (which will also let you inspect the types, edit the code, etc)

urban ether
#

lol, omg. Thanks for not bailing cuz I was crazy 🙂 !