Tips for deleting a dynamic property from a predefined TypeScript base class

Let's say I have a third-party base class structured like this:

export class Base {
    [k: string]: any;
    foo(): number;
    bar(): number;
};

I need to inherit from this base class, but I want to remove the dynamic key in my object. Is there a way to achieve that?

For example, I would like to be able to safely write code like this:

class Child extends Base {
    // Remove all dynamic keys
    // Essentially make it inaccessible within my TypeScript code.
    bzx(): number { return 3; }
}

const b = new Child();
b.foo() // OK;
b.bzx() // OK;
b.baz() // not allowed;

I attempted to follow the example for FunctionProperties<T> mentioned in the TypeScript documentation, but encountered issues when handling T with [k: string]:any property.

Eventually, based on the advice provided in the accepted answer, I ended up duplicating the entire declaration file of the base class, excluding the: [k: string]: any

Then, I transformed it into an interface rather than a class.

So, in practice, the process looked something like this:

import { Base } from 'Base';
import { IBase } from 'my/own/custom/IBase.ts'
class Child extends (Base as (new () => IBase)){ ... }

It could be argued that the approach above is slightly more refined because mixins played a role. Therefore, it resembles something along these lines:

function mix<C extends IBase>(base: Constructor<IBase>){ 
   return class extends base { .... }
}

class Child extends mix(Base){ ... }

Answer №1

Unfortunately, retrieving keys from the non-dynamic part of a type is not possible. When using keyof, it will always return string for the type Base. However, a workaround is to use Pick to extract the properties of the non-dynamic keys. If you are willing to manually list out all the keys, you can achieve this as shown below:

export declare class Base {
    [k: string]: any;
    foo(): number;
    bar(): number;
};

const SafeBase = Base as (new () => Pick<Base, 'foo' | 'bar'>)
class Child extends SafeBase {
    bzx(): number { return 3; }
}

const b = new Child();
b.foo() // OK;
b.bzx() // OK;
b.baz() // not allowed;

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

What is the method to incorporate a fresh generic parameter without officially announcing it?

My goal is to define a type union where one of the types extends an existing type: // The original type type Foo<V> = { value: V; onChange: (value: V) => void }; // Type union incorporating Foo type ADT = ({ kind: "foo" } & Foo<a ...

Having trouble installing the gecko driver for running protractor test scripts on Firefox browser

Looking to expand my skills with the "Protractor tool", I've successfully run test scripts in the "Chrome" browser. Now, I'm ready to tackle running tests in "Firefox," but I know I need to install the "gecko driver." Can anyone guide me on how t ...

Why is TypeScript unable to recognize package exports? (using CommonJS as the module system and Node as the module resolution)

I have an NPM package that is built for ESM and CJS formats. The package has a dist folder in the root directory, which contains: dist/esm - modules with ESM dist/cjs - modules with CJS dist/types - typings for all modules In the package.json file, there ...

Determine whether the radio button has been selected

Within my HTML code, there's a radio button enclosed in a form: <mat-radio-button [(ngModel)]="boxChecked" name="boxChecked" value="boxChecked">Check me</mat-radio-button> In the TypeScript section, I've declared my boolean variable ...

Discover how to showcase the balances of various supported networks through the Wagmi Library in a React application, just like how it's executed in

When using wagmi to connect to my wallet through the Metamask connector, I want to display the balances of different supported chains. For example, if the supported chains array includes [polygon, base, optimism], I can only retrieve the overall account ba ...

Is there a more effective method to return a response apart from using a redundant function?

function unnecessaryFunction(){ let details: SignInDetails = { user: user, account: account, company: company }; return details; } I am being told that the details value is unnecessary. Is there ...

The `message` binding element is assumed to have a type of `any` by default

I am trying to send data from parent component to child component, but I am encountering an error: Binding element 'message' implicitly has an 'any' type. Can someone assist me with my code? const Forms = () => { const [messageTe ...

Using a function as a parameter in Typescript: Anticipated no arguments, received 1.ts

I'm encountering an issue when trying to pass the doSomething function into performAction. The error message I'm receiving is Expected 0 arguments, but got 1 interface SomeInterface { name: string, id: string } function doSomethingFunction( ...

Using TypeScript to filter and compare two arrays based on a specific condition

Can someone help me with filtering certain attributes using another array? If a condition is met, I would like to return other attributes. Here's an example: Array1 = [{offenceCode: 'JLN14', offenceDesc:'Speeding'}] Array2 = [{id ...

Make sure to include all enum type values within the function's body to ensure comprehensive coverage

I am defining an enumeration called ApiFunctions with values like "HIDE", "SET_READ_ONLY", and "DESCRIPTION". Also, I have a type ValueOfApiFunction that should include all values of ApiFunctions. Additionally, I have a logic that listens for messages on ...

The condition will be false if a number is present, even if it is zero

I am facing an issue with a class containing an optional field called startDateHour: export class Test { startDateHour?: number; // more fields, constructor etc. } I need to perform an action only if the startDateHour exists: if (test.startDateHour ...

How can Angular components communicate with each other through a shared service?

Recently, I dived into learning Angular and came across an interesting example in the official documentation discussing parent-child communication using a service: import { Injectable } from '@angular/core'; import { Subject } from 'rxjs&apo ...

Interpolating strings with Angular does not result in binding

My goal is to populate the template using string interpolation. However, when I attempt to reference the variable in the template, I receive the following error: core.js:1350 ERROR TypeError: Cannot read property 'status' of undefined. HTML ...

In what way can you retrieve scope values (when testing) from an Angular controller implemented in TypeScript?

When working with Angular controllers in TypeScript, you have the option to define your controller in a way that accepts the $scope as an input parameter: class TestCtrl { constructor($scope:ng.IScopeService) { $scope.myData = "Information"; ...

Pause and be patient while in the function that delivers an observable

I have a function that loads user details and returns an observable. This function is called from multiple places, but I want to prevent redundant calls by waiting until the result is loaded after the first call. Can anyone suggest how this can be accompli ...

Adjusting an item according to a specified pathway

I am currently working on dynamically modifying an object based on a given path, but I am encountering some difficulties in the process. I have managed to create a method that retrieves values at a specified path, and now I need to update values at that pa ...

What is the proper way to specify the type for a <video> element reference in React when utilizing Typescript?

I have been experimenting with controlling the play/pause state of a video in React.js using ref's. My code functions correctly but I am encountering tslint errors that I am currently trying to diagnose: function App() { const playVideo = (event:a ...

Accordion's second child element experiencing issues with grid properties

I have set the parent element display:"Grid" and specified the gridColumnStart for my child elements as shown below. It seems to be working correctly for the first child element, but not for the second one. Please find my code attached: return ( ...

To utilize a spread argument, it is essential for it to either be in tuple form or be supplied to a rest

I am currently learning TypeScript and working on converting my project to TypeScript. However, I encountered an error while trying to use spread arguments. I have researched this topic, but I am still unsure of the correct usage. Here is my current appro ...

Issue with arrow function not being invoked in a React TypeScript component's prop inside a function

My parent component holds a useState hook to determine if the mobile Nav is open or closed: const [showMobileMenu,setShowMobileMenu] = useState<boolean>(false);. To close the mobile menu, I created an arrow function and passed it down to a child comp ...