Hello everyone, I was running into a problem recently that I somehow can't figure out how to solve:
I created a module called "lib" which exports a function and a type:
// lib/index.ts
export type Foo = {
bar: string;
};
export const foo = { bar: "baz" };
I then import this module in another file and try to use the type and the function:
// src/index.ts
import { Foo, foo } from "../lib";
So far, this works fine. However the import is pretty verbose and I would like to make my life easier and import the type and the function in one go and access it with a single name:
// (1) import everything using a default export
import Lib from `../lib`;
type alias = Lib.Foo;
const moreFoo = Lib.foo;
// (2) import a namespace
import { Lib } from `../lib`;
type alias = Lib.Foo;
const moreFoo = Lib.foo;
// (3) import everything using a named export
import * as Lib from `../lib`;
type alias = Lib.Foo;
const moreFoo = Lib.foo;
v3 works, but I don't like the * as syntax; this would be my last resort if i can't find a way to make v1 or v2 work.
To make v1 or v2 work obviously I have to change my module to export a default (v1) or a namespace (v2) instead of exporting the type and the function directly:
// lib/index.ts (v1: use default export)
type Foo = {
bar: string;
};
const foo = { bar: "baz" };
export default {
Foo, // this will not work: Foo is a type and can't be used a value
foo
};
// lib/index.ts (v2: use namespace)
export namespace Lib {
export type Foo = {
bar: string;
};
export const foo = { bar: "baz" };
}
In v1 I can't figure out how to default export a type as well as an object. Is that possible?
In v2 I have a bit more complicated problem: while my module is meant for the frontend there is also an extension for the backend (some database stuff). The backend extension is in a separate file and I would like to export the namespace in the main file and extend it in the backend file. However, I can't figure out how to extend the namespace in the backend file. Is that possible?
I am looking for something like this:
// lib/server.ts
import { Lib } from "./index";
export namespace Lib {
// "inherit" the namespace Tag from './index'
export const additionalFoo = "bar"
}
So here the problem is that I can't figure out how to extend the namespace Lib with the extension only being present when importing import { Lib } from "./server" and not when importing import { Lib } from "./index".
To get to my question -- is there a way to be able to import my whole module (type and function) without using import * as Lib... and still be able to access it like so:
import { Lib } from `../lib/index`; // or whatever way I should use to import the module
type alias = Lib.Foo;
const moreFoo = Lib.foo;
const evenMoreFoo = Lib.additionalFoo; // this should error here since it's only available when importing from server file
// server file
import { Lib } from `../lib/server`; // or whatever way I should use to import the module
type alias = Lib.Foo;
const moreFoo = Lib.foo;
const evenMoreFoo = Lib.additionalFoo; // this should work here
Is my way to use namespaces? but then how can I "extend" the namespace for the server file?
Or should I go with default exports which I can easily extend in the server file but for which I can't figure out how to export a type and a value at the same time?
Or is there a completely different way to do this?