Guide on creating a Typescript function with a strongly typed argument

I am looking to develop a function that accepts a type created using export class and imported in the traditional manner as an extension of a particular type. With a base Page class and various derived classes, I aim to have this function capable of receiving the Page, DerivedPage, AnotherDerivedPage classes (not instances), all while maintaining strong typing without resorting to any.

What would be the best approach to achieve this?

Answer №1

If you're looking to specifically target classes like Page, DerivedPage, and AnotherDerivedPage, you can achieve this using the following method:

function exampleFunction (arg: Page | DerivedPage | AnotherDerivedPage)

To specify an argument that extends the Page class, you may want to consider the following approach:

function customFunction<T extends Page> (param: T) { ... }

UPDATE:
Here's an example demonstrating how to use such types with arrow functions:

type customType<T extends Page> = (value: T) => void
const myFunc: customType<DerivedPage> = (value) => { /* ... */ }

Answer №2

To utilize a constructor signature, follow the example below:

class Page {
    private p!: string;
}
class DerivedPage extends Page { }
class OtherPage extends Page { 
    constructor(param: number){
        super();
    }
}
class NotPage { private np!: string; }

function createPage(ctor: new (...a: any[])=> Page, ...a: any[]) {
    new ctor(...a);
}

If necessary, you can implement a more general version that retains parameter and class type:

//Maintains argument and class type
function genericCreatePage<T extends Page, A extends any[]>(ctor: new (...a: A)=> T, ...a:A){
    return new ctor(...a);
}

genericCreatePage(DerivedPage)
genericCreatePage(OtherPage, 0)
genericCreatePage(OtherPage, "0") //err

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

Expressjs makes it easy to upload audio files to your website

Currently, I'm developing a music app and I'm looking for the best way to upload an audio file in my ExpressJS application. Is it possible to use Cloudinary or is there another method that is more efficient? I attempted to follow the same proces ...

Define the interface for a GraphQL resolver argument in code-first implementation

This specific GraphQL schema example from the Constructing Types page showcases how to define the Query type. // Creating the Query type var queryType = new graphql.GraphQLObjectType({ name: 'Query', fields: { user: { type: userType ...

Angular, Transforming JSON with RxJS Operators in TypeScript

Upon receiving the JSON object (Survey) from the server, it looked like this: { "id": 870, "title": "test survey", "questions": [ { "id": 871, "data": ...

Using Vue.js 2 on multiple HTML pages with Typescript and ASP.Net Core

My ASP.Net Core MVC project utilizes VueJs2 for more complex tasks, with each view having its own corresponding js file. The directory structure is as follows: ├ Controllers\HomeController.cs (with actions Index & Details) ├ Scripts\Hom ...

Unable to utilize React Icons component as an object value in typescript

Currently, as I develop my personal website using typescript and react, I am faced with an issue in the footer section. I have an array of objects with url and icon properties that I map through to display different icons on each iteration. Initially, this ...

Angular 2 components not properly handling two-way binding errors

Exploring how to achieve two-way binding in Angular 2, I am currently working with the following parent component setup: app.component.html: <child [(text)]="childText" (textChanged)="textChanged($event)"></child> <span>{{childText}}< ...

Utilizing TypeORM in a Node.js Project

Recently, I was exploring different ORM options for my server application and came across TypeORM. I'm curious to know the best approach to organize a small project using it. While browsing through the official documentation, I found a repository that ...

The current context for type 'this' cannot be assigned to the method's 'this' of type '...'

Currently, I am in the process of defining type definitions (.d.ts) for a JavaScript library. In this specific library, one of the methods accepts an object of functions as input, internally utilizes Function.prototype.bind on each function, and then expos ...

Is it possible to utilize the OnBlur prop based on a certain condition?

To display a component when the input is focused, follow the steps below: Click here for not focused state When you click on the text input, the component should appear like this: Click here for focused state The code snippet provided works correctly. ...

React TypeScript - Issue with passing props to Hooks causing type errors

I have set up a codesandbox project to demonstrate my problem 1) Initially, I created the <Input> component for styling and tracking input content. 2) While everything was functional, adding more forms prompted me to create a useInput hook for easi ...

Creating a dynamic type class in TypeScript that can inherit characteristics from another class

Can a wrapper class be designed to dynamically inherit the properties of another class or interface? For instance... interface Person { readonly firstName: string; readonly lastName: string; readonly birthday?: Date } class Wrapper<T> { ...

What is the process for defining an opaque type in programming?

[ This is not this ] Take a look at this snippet of code: interface Machine<OpaqueType> { get(): OpaqueType, update(t: OpaqueType); } const f = <U, V>(uMachine: Machine<U>, vMachine: Machine<V>) => { const u = uMach ...

tsc is not recognizing the configurations in my tsconfig.json file

Running tsc in my project's directory is causing an error to be outputted (as shown below). This is my first attempt at using TypeScript and Node.js. Please consider me as a complete beginner. Operating system: Ubuntu 15.10 64bits NPM version: 2.4. ...

Creating a function that utilizes a default argument derived from a separate argument

Consider this JavaScript function: function foo({ a, b, c = a + b }) { return c * 2; } When attempting to add type annotations in TypeScript like so: function foo({ a, b, c = a + b }: { a?: number, b?: number, c: number }): number { return c * 2; } ...

Is it possible to retrieve a constant value while developing a customized rule in typescript-eslint?

I am currently working on implementing a custom ESLint rule using @typescript-eslint/utils that will display a warning if the prop kind of Category does not match a specific Regex pattern: import { ESLintUtils, TSESTree } from '@typescript-eslint/util ...

What is the best way to test the SSM getParameter function using Jasmine?

Is there a way to effectively test this? const ssmParameterData = await ssm.getParameter(params, async (error, data) => { if (error) throw error; return data; }).promise(); I have attempted mocking the method by doing: spyOn(ssm, 'getParameter& ...

Using the setupFiles option to set up files and execute code prior to running tests

I need to ensure that some code is executed before all tests are run. My jest.config.js setup: // truncated... setupFilesAfterEnv: [ "./jest.setup.ts" ] The content of jest.setup.ts: async function setUp() { const first = new Prom ...

Issue with NestedKeyof type arising from circularly referencing objects

Currently, I am in the process of constructing a library and my task involves implementing NestedKeyof. During my research, I came across the following code snippet: type NestedKeyOf<T extends object> = { [Key in keyof T & (string | number)]: ...

Taunting a specific occurrence inside a group

Good evening, I am currently in the process of developing tests for the TypeScript class shown below. My goal is to create a test that ensures the postMessage method of the internal BroadcastChannel is called. However, I am facing difficulties in setting ...

Unexpectedly, a significant ngrx createEffect leads to an unusual error following an update, but the issue vanishes when certain code snippets like tap or filter are disabled

I have been in the process of upgrading a massive Angular 12 project to Angular 13 and have completed several steps. One significant change was the rewriting of Effects using a newer approach like createEffect(() => instead of @Effect However, during ...