Prevent assignment of properties from a subclass

Let's consider the scenario below:

interface Base {
  a: string;
}

interface Derived extends Base {
  b: string;
}

const x: Derived = {
  a: "a",
  b: "b",
};

How can we configure the linter and/or compiler to detect any issues with the following line:

const y : Base = x;

The objective is to identify any extra properties being assigned to y that are not defined in the Base class.

Answer №1

The comment provided at this link explains that TypeScript follows a structurally-typed approach.

This implies that when extending Derived from Base, it is not possible to exclude properties of Base from Derived.

However, by utilizing structural typing, you can create an additional type that remains compatible with Base while excluding any "extra" properties present in Derived. This can be achieved by defining them as optional properties of type never (using certain type utilities), like so:

Take a look at the TS Playground for implementation details.

interface Base {
  a: string;
}

interface Derived extends Base {
  b: string;
}

const x: Derived = {
  a: "a",
  b: "b",
};

type PreventExtendedProps<Base, Derived extends Base> = Base & Partial<Record<Exclude<keyof Derived, keyof Base>, never>>;

type BaseNotDerived = PreventExtendedProps<Base, Derived>;

// Check the type's properties:
declare const b: BaseNotDerived;
b.a // string
b.b // undefined

// Example assignment scenario:
const y: BaseNotDerived = x; /*
      ^
Type 'Derived' cannot be assigned to type 'BaseNotDerived'.
  Type 'Derived' cannot be assigned to type 'Partial<Record<"b", never>>'.
    Properties of 'b' are incompatible.
      Type 'string' cannot be assigned to type 'never'.(2322) */

Answer №2

Consider this scenario...

interface ModelA = {
    propertyA: string;
};

interface ModelB = {
    propertyB: string;
};

type UnionModel = ModelA | ModelB;

const value: UnionModel = {
    propertyA: "value A",
    propertyB: "value B",
};

const objectA: ModelA = { propertyA: "123" };
const objectB: ModelB = { propertyB: "234" };
const unionObject: UnionModel = value;

const objB: ModelB = value; // <---- Error
const objA: ModelA = value; // <---- Error

It appears that using only interfaces will not suffice in this case

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 on linking a trust policy to an IAM role through CDK

{ "Version": "2008-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": [ ...

Retrieve objects from an array that contain a certain specified key

I am trying to extract the objects from All_reports that contain the key: comentarioAdmin. Currently, I am retrieving all reports from All_reports, but I only want the reports that have the key comentarioAdmin. Thank you! getReports() { this.Service.g ...

Ways to resolve the issue of npm being unable to globally install typescript

While trying to globally install TypeScript using npm sudo npm install -g typescript An error occurs during the installation process with the following message: ENOENT: no such file or directory, chmod '/usr/local/lib/node_modules/typescript/bin/ ...

Struggling to properly import the debounce function in ReactJS when using TypeScript

I am facing an issue while trying to properly import the debounce library into my react + typescript project. Here are the steps I have taken: npm install debounce --save typings install dt~debounce --save --global In my file, I import debounce as: impo ...

I'm encountering an issue with my Next.js development server at localhost:3001 where all routes are displaying a 404 not found page. What

Currently working on a Next.js dashboard app and encountering an issue where my localhost keeps redirecting me to the 404 page. This has happened before, but I can't recall how I resolved it. Here is the recurring problem: I attempted deleting the .n ...

`Is There a Solution When Compilation Fails?`

I keep encountering an issue when I run the command npm start. The problem seems to be originating from PancakeSwap Frontend and after several attempts, I am still unable to resolve it. Your assistance is greatly appreciated :) Below is a snippet of my Ap ...

Locate the nearest upcoming date and time to today's date in the JSON response

I am currently working with an API that provides a response containing the `start_time` field in JSON format. My goal is to extract the ID from the JSON object whose next date time is closest to the current date and time, excluding any dates from the past. ...

Data can be retrieved in a React/Next.js application when a button is clicked, even if the button is located in a separate

Whenever the button is clicked, my function fetches weather data for the current location. I am trying to figure out how to transfer this data from the Location component to the pages/index.tsx. This is where another component will display the data. This ...

Achieving the incorporation of multiple components within a parent component using Angular 6

Within parent.component.html The HTML code I have implemented is as follows: <button type="button" class="btn btn-secondary (click)="AddComponentAdd()">Address</button> <app-addresse *ngFor="let addres of collOfAdd" [add]="addres">< ...

Utilizing the "as" keyword for type assertion in a freshly created react application using create-react-app leads to the error message `Parsing error: Unexpected token, expected ";"`

After creating a new CRA project using yarn create react-app my-app --template typescript, I encountered an error when trying to run the development server with yarn start: src/App.tsx Line 5:24: Parsing error: Unexpected token, expected ";" ...

Creating dynamic Kafka topic names within a NestJS microservice

Currently in Nestjs, I have integrated Kafka as my message broker and specified the topic name like so: @MessagePattern('topic-name') async getNewRequest(@Payload() message: any): Promise<void> { // my implementation logic } I am curious ...

Learn how to alter the website's overall appearance by changing the background or text color with a simple click on a color using Angular

Is there a way to dynamically change the background color or text color of the entire website when a user clicks on a color from one component to another? I know I need to use the Output decorator, but how can I implement this? style.component.html <di ...

Tips for transferring state information from a client to a server component within Nextjs?

Currently, I am working on a project where I need to read and write data from a locally stored .xml file that contains multiple <user> tags. The technology stack includes TypeScript and NextJS. The project is divided into three main components sprea ...

Utilizing pattern matching in switch statements

Imagine I have different APIs that provide data about various animals. Despite some shared properties, the JSON payloads for each animal type are quite unique and specific. To avoid chaos in my code, I am looking to create strongly typed TypeScript classe ...

Choose the object's property name using TypeScript through an interface

Consider a simplified code snippet like the following: interface MyBase { name: string; } interface MyInterface<T extends MyBase> { base: MyBase; age: number; property: "name" // should be: "string" but only p ...

The flatMap function is not operating as intended in the sequence of function calls

Having difficulty organizing a chain of calls using TypeScript with RxJS observables I am new to RXJS and I am struggling to structure a chain of calls in my TypeScript code. My question is - how can I ensure that this.http.get(''); is only cal ...

using outlines for FontAwesome icons in React Native

I am struggling to use the fontAwesome + icon in the middle of a circle as one item. I have tried placing it inside a circle icon, but it doesn't seem to work properly. import IconFA from 'react-native-vector-icons/FontAwesome'; < ...

"Exploring the process of extracting data from a JSON URL using NextJS, TypeScript, and presenting the

After tirelessly searching for a solution, I found myself unable to reach a concrete conclusion. I was able to import { useRouter } from next/router and successfully parse a local JSON file, but my goal is to parse a JSON object from a URL. One example of ...

What method can be used to inherit the variable type of a class through its constructor

Currently, I am in the process of creating a validator class. Here's what it looks like: class Validator { private path: string; private data: unknown; constructor(path: string, data: string) { this.data = data; this.path = path; } ...

Utilizing References in React Components

One of the challenges I am facing involves a Container that needs references to some of its child components: const Container = () => { const blocks: HTMLDivElement[] = []; return ( <div> <Navigation currentBlock={currentBlock} ...