What purpose does a private property serve within the interface?

Given the following code snippet:

class X  {
    bar() {
        return "bar"
    }
    constructor(private readonly x: number){}
}

interface Y extends X {
}


const f = (y: Y) => { console.log(y.bar()); }

f({ bar: () => "tavern"});

The code does not compile due to the missing x.

f({ bar: () => "tavern", x: 1});

Another attempt that fails to compile because x is not private.

Trying to rewrite the code to ensure that x can be declared as private results in this rejected solution:

class Y implements X {
    bar() {
        return "tavern"
    }
    private x = 1;
}

This approach is ineffective due to the issue of "types having separate declarations."

The only viable solution discovered so far involves removing the private keyword from the constructor.

Ideally, the preference is for the initial solution where there's no concern about private properties or members within the constructor.

Two main questions arise:

  1. Why does this occur?
  2. Is there a way to avoid dealing with private properties altogether?

Answer №1

Ryan Cavanaugh, the development lead for Microsoft's Typescript team, shared his thoughts in a comment:

He emphasized that allowing private fields to be missing would not just be a minor issue, but a significant problem affecting the overall soundness of the code.

To illustrate this point, consider the following code:

class Identity {
  private id: string = "secret agent";
  public sameAs(other: Identity) {
    return this.id.toLowerCase() === other.id.toLowerCase();
  }
}

class MockIdentity implements Identity {
  public sameAs(other: Identity) { return false; }
}

In this example, MockIdentity seems like a compatible version of Identity, but using it as such will cause a crash in the sameAs method when a non-mocked instance interacts with a mocked one.

This situation is frustrating and can lead to problems.

However, a workaround was discovered to address this issue:

type Public<T> = {
    [P in keyof T]: T[P];
};

class X  {
    bar() {
        return "bar"
    }
    constructor(private readonly x: number){}
}

interface Y extends Public<X> { }

const f = (y: Y) => { console.log(y.bar()); }

f({ bar: () => "tavern"});

This workaround allows for mocking complex types effectively without having to mock out private data as well.

It is important to note that this approach is primarily intended for use in testing contexts where interactions between mocked and genuine instances are limited.

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

Produce new lines of code using the vscode.window.activeTextEditor.edit method in Visual Studio Code

Hey everyone, I'm currently working on a vscode extension that can automatically generate template code based on the language you are using when you click a button. However, there seems to be an issue with the formatting of the generated code as it do ...

Encountering an issue with MUI Props: "Must provide 4 to 5 type arguments."

I'm attempting to use a custom component and pass in AutocompleteProps as a prop, all while utilizing typescript. Here's my current setup: type Props = { autoCompleteProps?: AutocompleteProps<T> label: string loading?: boolean } cons ...

What is the method in XState to trigger an event with the parameters send('EVENT_NAME', {to: 'a value from the context'})?

I want to send an event to a different spawned state machine using its ID, which I have stored as a string in a variable within the context. This state machine is neither the parent nor child. For example: context.sendTo = 'B_id' How can I use ...

Displaying Typescript command line options during the build process in Visual Studio

As I delve into the world of VS 2015 Typescript projects, I find myself faced with a myriad of build options. Many times, the questions and answers on Stack Overflow mention command line options that I'm not completely familiar with, especially when i ...

Trigger a dispatched action within an NGRX selector

I want to ensure that the data in the store is both loaded and matches the router parameters. Since the router serves as the "source of truth," I plan on sending an action to fetch the data if it hasn't been loaded yet. Is it acceptable to perform the ...

Implementing a conditional chaining function in TypeScript

I'm currently facing an issue while implementing a set of chained functions. interface IAdvancedCalculator { add(value: number): this; subtract(value: number): this; divideBy(value: number): this; multiplyBy(value: number): this; calculate( ...

Can the automatic casting feature of TypeScript be turned off when dealing with fields that have identical names?

Imagine you have a class defined as follows: Class Flower { public readonly color: string; public readonly type: string; constructor(color: string, type: string) { this.color = color; this.type = type; } Now, let's introduce anoth ...

Enhance your map by incorporating an overlay with ngx-openlayers

Currently, I am trying to implement zoom-in and zoom-out buttons on an OpenLayers map. I attempted to use the overlay method but encountered an error. Here is the code snippet for reference: zoom_button = document.getElementById('zoom') zo ...

Retrieving information selectively using useSWRImmutable

Having issues fetching data using useSWRImmutable. The problem arises when attempting to display the fetched data inside the UserRow component. Even though I can successfully print the data outside of the UserRow component, any console.log() statements wi ...

What is the best way to inform TypeScript that the output of the subscribe method should be recognized as an array containing elements of type

I'm facing a challenge understanding types while working with noImplicitAny and typescript in Angular 6. The compiler is indicating that the type of result is Object, even though I am certain it should be an array of type Manufacturer. Unable to assig ...

Implementing indexers in TypeScript to accommodate both string and numeric keys

Seeking to incorporate different types into existing code. In the code, there exists a transitionData object in which objects can be added by index as shown below: this.transitionData[id] = transition where id is a number and transition is of type Trans ...

Is there a way to create a TypeScript function that can accept both mutable and immutable arrays as arguments?

Writing the following method became quite complicated for me. The challenge arose because any method receiving the result from catchUndefinedList now needs to handle both mutable and immutable arrays. Could someone offer some assistance? /** * Catch any ...

The type 'string' cannot be assigned to the type 'T[keyof T]' within this context

I have a function that processes an array of Episodes and assigns data from an external file to the corresponding Episode based on a specified keyName: const assignDataFromExternalFile = (arrayToProcess: Episode[], filePath: string, keyName: keyof Episode) ...

Is there a way to simulate AWS Service Comprehend using Sinon and aws-sdk-mock?

As a newcomer to Typescript mocking, I am trying to figure out how to properly mock AWS.Comprehend in my unit tests. Below is the code snippet where I am utilizing the AWS Service Comprehend. const comprehend = new AWS.Comprehend(); export const handler ...

Node.js does not allow the extension of the Promise object due to the absence of a base constructor with the required number of type

I'm trying to enhance the Promise object using this code snippet: class MyPromise extends Promise { constructor(executor) { super((resolve, reject) => { return executor(resolve, reject); }); } } But I keep encou ...

Tips for arranging various information into a unified column within an Antd Table

Is there a way to display multiple data elements in a single cell of an Ant Design table, as it currently only allows insertion of one data element? I am attempting to combine both the 'transactionType' and 'sourceNo' into a single cell ...

Prevent a React component from unnecessarily re-rendering after a property has been set

I am working on a react component that displays a streaming page similar to the one shown in this image. Here is a snippet of the code : const [currentStream, setCurrentStream] = useState<IStream>(); const [currentStreams] = useCollectionData<ISt ...

Could you please explain the significance of /** @docs-private */ in Angular's TypeScript codebase?

After browsing through the @angular/cdk code on GitHub, I came across a puzzling "docs-private" comment. Can anyone explain its significance to me? Link to Code * In this base class for CdkHeaderRowDef and CdkRowDef, the columns inputs are checked for ...

NextJS introduces a unique functionality to Typescript's non-null assertion behavior

As per the typescript definition, the use of the non-null assertion operator is not supposed to impact execution. However, I have encountered a scenario where it does. I have been struggling to replicate this issue in a simpler project. In my current proj ...

Unveiling the Power of USSD Codes with Ionic Typescript: A Comprehensive Guide

Currently diving into the world of Ionic 2 Framework, I find myself on a quest to discover how to execute USSD codes in Ionic using Typescript. Any guidance or assistance from the community would be greatly appreciated! ...