Using TypeScript to explicitly define a subtype

Given a base type A, I am looking to create a sub-type B that is assignable to A without any additional properties, and enforce this assignability.

Illustration

Starting with the following type:

interface A {
  name?: string;
  age?: number;
}

I aim to establish the following type:

interface B {
  name: string;
}

In essence, any instance of type B should be assignable to type A, maintaining strict adherence. If any extra property is added, TypeScript should raise an error.

Potential Pitfalls

  1. Utilizing extends might lead to a less stringent result than desired:
interface B extends A {
  name: string;
}

This formulates as:

interface B {
  name: string;
  age?: number;
}

Furthermore, it permits adding non-existent properties for Person.

  1. The approach of A extends B is not viable due to A already being predetermined; the goal is to craft type B.

Answer №1

When looking for specific fields that already exist in A, an alternative method to consider would be:

type OnlyExisting<X, Y extends X> = {
  [Key in keyof Y]: Key extends keyof X ? Y[Key] : never;
}

type D = OnlyExisting<A, { age: number; }>;

This approach does not prevent you from defining

type E = OnlyExisting<A, {
  age: number;
  bar: string;
}>;

// E results in { age: number; bar: never }

However, it ensures type safety by instructing TypeScript to overlook fields that do not appear in X. Therefore, any function expecting A should still welcome E without issues;

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

incorporating a personalized HTMLElement using Typescript

Hey there! I'm fairly new to using Angular and could use some help. I'm trying to insert a custom HTML element onto a page when a button is clicked, but I'm struggling to figure it out. Here are my HTML and TypeScript files: TypeScript Fil ...

The parent component remains visible in the Angular router

Within my appComponent, I have a layout consisting of a toolbar, footer, and main content. The main content utilizes the router-outlet directive structured as follows: <div class="h-100"> <app-toolbar></app-toolbar> < ...

Generating Enums from JSON REST API in Angular 8

Is there a way to create an enum from a JSON REST API? Here is the code I currently have in my service.ts file: getDataFromJson(): Observable<any> { return this.httpClient.get<any>(`../../../assets/gender.json`) .pipe(map(data => ...

Determining whether a variable is an instance of FirebaseApp

I'm working with this simple codebase import { FirebaseApp, FirebaseOptions } from "firebase/app"; function example(app){ // error: FirebaseApp only refers to a type console.log(app instanceof FirebaseApp) } In this scenario, the Firebase ...

Mongoose TypeScript Aggregation error: is not a valid property of type 'any[]'

Attempting to replace a standard mongo call with an aggregate call. The original code that was functional is as follows: const account = await userModel .findOne({ 'shared.username': username }) .exec(); console.log(account._id) The n ...

Obtain the user's ID in string format from the clerk

I'm trying to retrieve the clerk ID to cross-reference with the backend. The issue is that the clerk is using a hook which isn't compatible with this function type. export const getServerSideProps = async ({ req }) => { const { isLoaded, is ...

How to transform a file into a uInt8Array using Angular

Looking to implement a feature where I can easily upload files from Angular to PostgreSQL using a Golang API. In my Angular component, I need to convert my file into a uInt8Array. I have managed to convert the array, but it seems to be encapsulated in som ...

The information that is visible in the console is failing to appear in the view

My issue revolves around retrieving data from Firestore. While the console displays the data correctly, my view ends up showing empty cards. Consider the following HTML code: <ion-grid> <ion-row> <ion-col size="12" > ...

Change the initial characters of a string according to specific categories

What is the best way to capitalize the first letter of a string based on specific conditions like those shown below? booking_engine → Booking Engine booking-engine → Booking Engine bookingEngine → Booking Engine crsProvider → CRS Provider crs_ ...

Creating nested return types: A guide to defining function return types within a Typescript class

My large classes contain functions that return complex objects which I am looking to refactor. class BigClass { ... getReferenceInfo(word: string): { isInReferenceList:boolean, referenceLabels:string[] } { ... } } I am considering somethi ...

Having trouble retrieving spot price using Uniswap SDK due to a transaction error LOK

const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle( immutables.token0, immutables.token1, immutables.fee, amountIn, 0 ) I set up a pool on Uniswap V3 for two ERC20 dummy tokens by using the createPool() met ...

Why do I keep encountering the error "global is not defined" when using Angular with amazon-cognito-identity-js?

To start, run these commands in the command line: ng new sandbox cd .\sandbox\ ng serve Now, navigate to http://localhost:4200/. The application should be up and running. npm install --save amazon-cognito-identity-js In the file \src&bso ...

How can I create a computed field in TypeORM by deriving its value from other fields within the same Entity?

My goal is to implement a 'rating' field in my User Entity. Within the User Entity, there exists a relationship with the Rating Entity, where the User has a field called ratingsReceived that eagerly loads all Ratings assigned to that User. The & ...

What is the best way to combine two observables in Angular using RxJS?

In my service, I have the following methods: getMap(): any { return this.http.get(`someURL`); } getAssets(): any { return this.http.get(`someURL`); } Within my Component, these methods are utilized in the following manner: ngOnInit() { ...

Angular error TS2322 arises when attempting to assign a type of 'Observable<{}>' with the share() operator

Currently diving into Angular 5, I've been exploring the Observable/Observer pattern to facilitate event sharing and data changes among subscribers. Below is a snippet of the code in question: ... @Injectable() export class NidoService { ... eve ...

Unpacking and reassigning variables in Vue.js 3 using TypeScript

I am working with a component that has input parameters, and I am experimenting with using destructuring assignment on the properties object to reassign variables with different names: <script setup lang="ts"> const { modelValue: isSelected ...

The Angular TypeScript lexicon scope becomes obscured when nested within a third-party API event handler function

I'm having trouble managing scope context in an Angular component while working with a third-party API (ESRI ArcGIS JavaScript API 4.7). I am specifically struggling when trying to handle an event from the ArcGIS API using their event handler callback ...

I keep getting the error message "Element is missing a 'key' prop", even though I have already included a key in my loop. What could be the issue here?

Every <td> and <tr> in my code has a unique key assigned to it. Check out the complete code of my component below: export default function TableComponent( data: any ) { const columnNames = Object.keys(data.data); const rowIndices = Obj ...

Steps to develop a sub-route specifically for a single word

Take a look at this code: {path : 'recipes', component:RecipesComponent, children:[ {path:':id', component:RecipeDetailComponent}, {path:':new', component:NewRecipeComponent } ]}, No matter which link you use: h ...

Utilizing Generic Types in React TypeScript Functional Components

I'm currently developing a TypeScript React component that includes generic type props, so I define the React component as: export interface MyCompProps<T> { items: T[]; labelFunction: (T) => string; iconFunction: (T) => JSX.Element; ...