question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Consider adding a module level visibility modifier.

See original GitHub issue

Currently to protect integrity of data one can only use classes with private or protected fields. Classes are harder to work with compared to object literals. Being able to specify that certain fields are invisible to outside modules would be a valuable addition to support programming in functional style in TypeScript.

So what I am suggesting is to be able to specify whether a field of an interface is exported from a module or not. This also means that the instance of such interface can only be created within the module it is declared.

The similar features can be found in:

Issue Analytics

  • State:open
  • Created 9 years ago
  • Reactions:99
  • Comments:23 (8 by maintainers)

github_iconTop GitHub Comments

4reactions
jonaskellocommented, Jun 22, 2019

+1 for using modules over classes 😃.

I wonder if the ability to specify interfaces for modules could help here, perhaps using d.ts files to “seal” a module and selectively hide/show values and types?

You can sort-of do this today using export. I sometimes do plugin-like design where I have several modules that expose the same “interface”. Something like this:

plugin1.ts

const firstValue = 11;
export function foo(x: string): number {...}
export function bar(x: number): string {...}

plugin2.ts

const secondValue = 22;
export function foo(x: string): number {...}
export function bar(x: number): string {...}

main.ts

import * as Plugin1 from "./plugin1.ts"
import * as Plugin2 from "./plugin2.ts"

interface Plugin {
readonly foo: (x: string)=>number;
readonly bar: (x: number)=> string;
}

const plugins: ReadonlyArray<Plugin> = [Plugin1, Plugin2];

This will give errors if a module does not export according to the interface. However it is very implicit and having a more explicit way to model this would be nice.

I think having interfaces for modules would only cover exposing whole types or values? So in addition to that, to get field level privacy we need something like flow’s opaque types. With that we can expose a type from a module without exposing the fields outside the module.

2reactions
HarryGiffordcommented, Jun 21, 2019

This would be an extremely helpful addition to the language. It’s one place where taking Javascript that was written using modules instead of classes becomes difficult to translate into Typescript. It would be great if it could cover opaque simple types like string and number too.

Some examples in the wild are the file descriptor in Node’s fs.open function and a lot of the WebGL types, such as WebGLBuffer.

In my experience the reasons I’ve had for using modules and interfaces instead of classes are

  • Makes immutable style code easier, as you can de-structure objects and not lose their “class” type.
  • Easier to “tree-shake.”
  • Can be serialized and deserialized without losing the class which is good when you want to interpret some data from localStorage, from a webworker or from a network request as an object of a particular type.
  • No need to privilege a single argument. Class methods have an implicit this argument, which is one reason it’s hard to specify interfaces for them because the interface assumes that the this argument is implicit in each method in the interface. You have no way to specify the static methods that exist on that class. It’s also unwieldy to define methods that take in multiple instances of that class or multiple ways to create the class.

I wonder if the ability to specify interfaces for modules could help here, perhaps using d.ts files to “seal” a module and selectively hide/show values and types?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Visibility modifiers
The internal visibility modifier means that the member is visible within the same module. More specifically, a module is a set of Kotlin...
Read more >
New Access Modifier: package - Pitches
We propose to introduce a new access modifier package . This would limit the visibility of the symbols to only modules within a...
Read more >
Provide package-private visibility modifier (or another scope ...
Using package-private, all internal classes, which are not supposed to be consumed by external modules, are now public. The alternative would be to...
Read more >
Package protected alternative in Kotlin - visibility
Using it, you can encapsulate a part of your code inside a separate module. So, on top level declarations you can use. private...
Read more >
Controlling Access to Members of a Class (The Java ...
Access level modifiers determine whether other classes can use a particular field or invoke a particular method. There are two levels of access...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found