Maintain confidentiality of field type

I am facing an unusual scenario where I require a class property solely to retain a generic type without the intention of accessing it at runtime.

Here is an example of my class and utility type:

class Foo<T> {
    private _dummy!: T;
}

type UnwrapFoo<T extends Foo<any>> = T extends Foo<infer Unwrapped> ? Unwrapped : never;

The _dummy property is not utilized, but it is essential for the functioning of UnwrapFoo. Without it, the type T would be discarded, causing UnwrapFoo to lose its inference capabilities.

My predicament arises when TypeScript generates the corresponding .d.ts file. The type of _dummy gets erased due to it being a private property. The generated typings end up looking like this:

class Foo<T> {
    private _dummy;
}

Consequently, T gets discarded once again and UnwrapFoo stops functioning properly. Is there a suitable solution to preserve the type of _dummy? Making it public is an option, but I prefer not to do so since it should remain internal and inaccessible to users of the Foo class (also, it always holds the value undefined regardless of its declared type).

Answer №1

There is a lack of documentation regarding the suppression of private class properties in generated .d.ts files when using the --declaration compiler option. This behavior cannot be altered. The only reference to this issue can be found in this comment on GitHub, along with evidence from the source code of the declaration emitter which suppresses type annotations for private elements except in constructor parameter properties.

If you need to maintain a hidden internal field without external access, consider converting it to a protected property:

// foo.ts
class Foo<T> {
    declare protected _dummy: T;
}

// foo.d.ts
declare class Foo<T> {
    protected _dummy: T;
}

While not as secure as private, since it allows subclassing, it prevents direct access to the member instance.

Link to Playground with sample code

Answer №2

Remember that types in TypeScript do not translate into JavaScript code; they are simply metadata for you and the compiler. Types cannot be stored in variables.


When it comes to generating .d.ts files, keep in mind that if a property is marked as private, the type will not be included. This is because private properties are inaccessible outside of the class, making type definitions unnecessary. For example:

class Foo {
    private _dummy: string = '';
}

The resulting .d.ts file would look like this:

declare class Foo {
    private _dummy;
}

On the other hand, a public property will have type information since external entities can access it through the .d.ts file. Consider:

class Foo {
    public _dummy: string = '';
}

The generated .d.ts file would be:

declare class Foo {
    _dummy: string;
}

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

Listen for Events on HTML Elements Created Dynamically

While working inside the "downMouseBtn(event)" Event Handler, I decided to create a new element with the code <div id ="rectangle"></ div> Now, my next step is to establish an eventListener for this newly created item. Could someone guide me ...

Update information according to the drop-down choice made from a different, unrelated component in Angular

I have different components that are not related. When I select a company from the header component, I want to immediately display data that matches the selected company. Currently, the data changes only when I visit another page and then return, but I nee ...

Advantages of using ConfigService instead of dotenv

What are the benefits and drawbacks of utilizing @NestJS/Config compared to using dotenv for retrieving environment variables? Although I can create a class to manage all envvars in both scenarios, is it necessary? I am aware that @NestJS/Config relies on ...

Having Trouble Setting Default Value in React Typescript MUI Autocomplete

I am encountering an issue with my React and Typescript code using MUI with the use of hook form. The problem arises when trying to set a default value for an Autocomplete field, resulting in the following error message: I am seeking assistance in resolvi ...

Having trouble locating the asset at /home/runner/CDK_Test/frontend/frontendapp/build while executing CDK deploy with GitHub Action

When attempting to execute `cdk deploy` on GitHub Actions, I encountered an issue with finding the build from frontendapp. I double-checked the build path for any errors but found none. Interestingly, running `cdk deploy --all` locally successfully display ...

Issue with TypeScript in Vue3: Unable to access computed property from another computed property

In my Vue3 project with TypeScript, I am encountering an issue where I am unable to access the properties of the returned JavaScript object from one computed property in another computed property using dot notation or named indexing. For instance, when tr ...

Is it possible to have Partial<SomeClass> without any methods included?

When creating a class, I like to include a constructor that can accept any relevant members for the class: class AnotherClass { itemA: string; itemB: number; constructor(obj: Partial<AnotherClass>) { Object.keys(obj).forEach(key => this ...

What is the proper way to utilize a function in C# that integrates with a window form using TypeScript?

I am currently working on a code that is in c# and utilizes a web browser. My goal is to convert the existing JavaScript code to Angular 7 and Typescript. Below is the c# code and the corresponding JavaScript code used to access the c# function from JavaS ...

Tips for managing exceptions in Redux when handling HTTP requests

Currently, I am in the process of learning react alongside redux and redux-observable. My main focus at the moment is on understanding how to handle errors effectively. Here's what I have done so far: I successfully created a redux-observable epic t ...

Error: Unable to modify a property that is marked as read-only on object '#<Object>' in Redux Toolkit slice for Firebase Storage in React Native

Hey there! I've been working on setting my downloadUrl after uploading to firebase storage using Redux Toolkit, but I'm facing some challenges. While I have a workaround, I'd prefer to do it the right way. Unfortunately, I can't seem to ...

What is the best way to create an "ArraySimilar" class using TypeScript?

Can someone guide me on creating an ArrayLike class in TypeScript? Edit: Got the solution from @jcalz, it's working perfectly for me. class CustomArray<T> implements ArrayLike<T> { length: number [index: number]: T } ...

Is it possible for the Chrome debugger to locate TypeScript files that have not been served by the

I am creating .js.map files to assist in debugging my TypeScript code within Chrome. The js.map files specify the correct location of the TypeScript in the "sources" property. sourceRoot is set to "", and sources represent the path to the TypeScript code ...

What is the method for determining the type in this component configuration?

When working with a custom hook from React DnD, I encounter an issue where TypeScript restricts my access to the property of an item object in the drop function due to its unknown type. function MyComponent(props){ const [{item}, drop] = useDrop({ ...

Choosing radio buttons within rows that contain two radio buttons using ngFor

This section showcases HTML code to demonstrate how I am iterating over an array of objects. <div class="row" *ngFor="let item of modules; let i = index;"> <div class="col-md-1 align-center">{{i+1}}</div> <div class="col-md- ...

Is there a way to create a Typescript function that can automatically return either a scalar or array value without requiring the caller to manually cast the output

Challenge Looking for a solution to the following problem: save<T>(x: T | T[]) { if (x instanceof Array) { // save array to database } else { // save entity to database } return x } // client code let obj: SomeType = { // values here ...

The data type 'unknown' cannot be assigned to the type 'any[]', 'Iterable<any>', or (Iterable<any> & any[])

I have been working on creating a custom search filter in my Angular project, and it was functioning properly. However, I encountered an error in my Visual Studio Code. In my previous project, everything was working fine until I updated my CLI, which resul ...

Utilizing NgModelGroup nesting in various components for improved data management

Whenever I attempt to nest NgModelGroup inside another NgModelGroup, Angular seems to just ignore it. I'm currently utilizing Angular 12 and Template-driven Forms. Here is how my code appears: app.component.html <form #form="ngForm"> ...

Choose a duplicate of an element from an array using JavaScript

I have a function that receives an array of items as a parameter. Within this function, I need to locate a specific item and update one of its properties. const defaultGroup = find(groupedCustomFields, group => group.name === DEFAULT_GROUP); //[find][1 ...

What could be causing my webpack bundler to generate several main.js files?

After realizing that tree shaking was not working correctly due to compiling TypeScript to 'commonjs', I switched it to 'ES2015' and now my build output appears like this: click here for the image. Can anyone explain what is happening ...

A static factory method within an abstract class

I am currently developing a class system using Typescript. The main structure consists of an abstract class called Component, which includes a static method called create(). This method is utilized on child classes to generate specific instances. abstract ...