Selling with a variety of classifications

Is it possible to export in a different manner?

I have a module that exports an object, which may change. The internal access to the object should be more permissive than external:

// Module A.
export let obj = {
  publiclyAvailable: 0,
  noTouchy: 0,
};

const func1 = () => { obj.noTouchy; /* Ok. */ };
const func2 = () => { /* reassign `obj` */ };

// Module B.
import { obj } from './A.js';
obj.publiclyAvailable; // Ok.
// obj.noTouchy; // No!

Currently, I am using an unnecessary indirection and code interference into 'emit':

// Module A.
let objContainer = {
  _realObj: {
     publiclyAvailable: 0,
     noTouchy: 0,
  },
  get obj() { return this._realObj; },
  set obj(v) {
    this._realObj = v;
    obj = v;
  },
};
export let obj: { publiclyAvailable: number } = objContainer.obj;

However, writing objContainer.obj every time serves no real purpose.

There is also a trick with asserting, but it only works on the top level:

// Module A.
const hack: (x: typeof obj) => asserts x is { publiclyAvailable: number; noTouchy: number } = () => void 0;
export let obj: {
  publiclyAvailable: number
} = (() => ({
  publiclyAvailable: 0,
  noTouchy: 0,
}))();
hack(obj);
obj.noTouchy; // Works!
const func1 = () => { obj.noTouchy; /* Fails. */ };

Edit: Considered a less cumbersome way (although it still interferes needlessly):

// Module A.
let _obj = {
  publiclyAvailable: 0,
  noTouchy: 0,
}
export const obj = new Proxy({} as { publiclyAvailable: number }, {
  get(_, p: keyof typeof _obj) { return _obj[p]; },
  /* ... all other handlers, because that's what `Proxy` needs ... */
});

Answer №1

One approach is to utilize a Symbol as the property key and refrain from exporting it.

// file: person.js

const ageSymbol = Symbol('age');

// export
const john = {
  name: 'John',
  // ...
  [ageSymbol]: 20,
}

console.log('person.js:', 'age is', john[ageSymbol])

// file: main.js

// unable to access ageSymbol since it's not exported
// attempting to create a new symbol will also fail

console.log('main.js:', 'age is', john[Symbol('age')])

The underlying question here is: What is the purpose of taking this approach? If you're aiming to develop a library, consider adding documentation specifying that certain objects/properties are private. In the case of using Typescript, cast your object to an interface without including that specific field.

Below is an example in javascript:

export const myObject = {
  data: {},
  /** @private */
  __myPrivateProperty: true
};

And here is an example in typescript:

interface MyInterfaceWithSecret {
  data: any;
  secret: string;
}

export type MyInterfaceWithHiddenSecret = Omit<MyInterfaceWithSecret, 'secret'>;
// or
export interface MyInterfaceWithHiddenSecret {
  data: any;
}


const mySecretObject: MyInterfaceWithSecret {
  data: {},
  secret: 'shhh'
};

export const myPublicObject = mySecretObject as MyInterfaceWithHiddenSecret

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide to adding the current date into a URL with Angular

I'm a little confused at the moment and could use some guidance. My goal is to dynamically insert the current date into an API URL using Angular. Here is the progress I have made so far: Below is my Typescript code: import { HttpClient} from '@a ...

The correct method for handling arrays with overlapping types and narrowing them down again

When working with arrays containing different types in TypeScript, I often encounter issues with properties that are not present on all types. The same challenge arises when dealing with various sections on a page, different user roles with varying proper ...

The error at core.js:4002 is a NullInjectorError with a StaticInjectorError in AppModule when trying to inject FilterService into Table

While exploring PrimeNg Table control in my application - as a beginner in PrimeNg & Angular, I encountered an error No provider for FilterService! shown below: core.js:4002 ERROR Error: Uncaught (in promise): NullInjectorError: StaticInjectorError(AppMo ...

"Exploring the relationship between Typescript and Angular: transforming variables within different

Ever since I made the switch from JavaScript to TypeScript (Version 2.1.5), I have been facing an issue with the code that filters date selection. Despite my efforts, I haven't been able to find a good fix for it yet. Here are the two date-pickers: F ...

Executing methods sequentially in the ngOnInit lifecycle hook consecutively

Working with Angular15 has presented me with a challenge. In my app.component.ts file, I have two methods: “ngOnInit()”, as shown below. public ngOnInit(): void { this.getToken(); this.UserLoggedIn(); } I am looking to run the above two functions in ...

When initiating an Ionic project, you may notice a repeated message in the terminal saying, "[INFO] Waiting for connectivity with npm..."

I'm in the process of setting up a new Ionic project along with all the necessary dependencies. However, whenever I try to execute the command "ionic serve," I keep getting stuck at the continuous display of the message "[INFO] Waiting for connectivit ...

When HTMLElement focus is activated, it interrupts the flow of execution

(the code presented is in TypeScript and I'm working with Angular 5, but I don't think that's the issue, so prove me wrong!) I have a basic input field that triggers events in an Angular component. (EDIT: I've added the complete compo ...

"Efficiently storing huge amounts of data in MySQL in just 5

Interested in my tech stack: express + typeorm + mysql Seeking a solution for the following task: I have a csv file with over 100000 rows, where each row contains data such as: reviewer, review, email, rating, employee, employee_position, employee_unique_ ...

What is the best method to send a useState prop to a child component in TypeScript?

As I navigate my way through Typescript in a react application, I find myself exploring the process of describing a JavaScript object using TypeScript. This particular object will be integrated into a useState hook and then shared with a child component. ...

One way to declare i18next specifically in React's App.tsx file is by following these

In my React App.tsx file, I am looking for a way to declare const { t } = useTranslation() only once. After that, I want to be able to use { t(trans.things) } in my components without having to declare const { t } = useTranslation() again each time. Is t ...

What is the best way to prevent a font awesome icon from appearing in a span during data loading

I am currently working on an Angular 11 application where I have implemented an icon to trigger the loading of a graph. However, I have noticed that there is a delay in loading the graph when the icon is clicked. To prevent users from triggering the icon m ...

The issue persists wherein getBoundingClientRect fails to provide the accurate value following a resize

I have implemented a custom directive that appends a dropdown to the body when it is displayed. The logic functions correctly when executed within the ngAfterViewInit lifecycle, but I encounter issues when attempting to use the same logic within the wind ...

What should I do about typescript and ES6?

An error occurred while running my code: [0] app/components/people/details/PersonDetailComponent.ts(27,35): error TS2339: Property 'person' is missing from type '{}'. Here is the code snippet in question: export class PersonDeta ...

What could be causing the issue with dayjs dynamic importing in TypeScript?

Currently, I am developing a web screen within a .NET application and facing an issue with sending datetime preferences from the system to the web screen using CefSharp settings. AcceptLanguageList = CultureInfo.CurrentUICulture.Name In my TypeScript code ...

The type 'MutableRefObject<undefined>' cannot be assigned to the type 'LegacyRef<HTMLDivElement> | undefined'

I have created a customized hook that takes a ref object and observes its behavior: import { useState, useEffect, MutableRefObject } from "react"; const UseOnScreen = (ref: MutableRefObject<undefined>) => { const [isIntersecting, setI ...

Tips for ensuring that the DOM is fully rendered before executing any code

Before proceeding to the next functions, it is necessary to wait for the DOM to finish rendering. The flow or lifecycle of this process is outlined below: Adding an item to the Array: this.someFormArray.push((this.createForm({ name: 'Name& ...

Is it possible for an uninitialized field of a non-null literal string type to remain undefined even with strict null checks in

It seems that there might be a bug in Typescript regarding the behavior described below. I have submitted an issue on GitHub to address this problem, and you can find it at this link. The code example provided in that issue explains the situation more clea ...

Each property of an object has its own unique key, yet they all share the same data type

I have a single-use object with only three properties, all of which should be of the same type. The code below currently achieves this, but I'm curious if there is a more efficient way to declare the type for timingsObject: let timingsObject: ...

Using React JS to Sort an Array Based on a Specific String

Here I am again, this time dealing with reactjs. I have a json object containing two "rows", labeled as Description and ubication. My goal is to filter the array based on the Description field. How can I achieve this? The description is in text format, f ...

Utilize a variable within a regular expression

Can the variable label be used inside a regex like this? const label = 'test' If I have the regex: { name: /test/i } Is it possible to use the variable label inside the regex, in the following way? { name: `/${label}/i` } What do you think? ...