The magic of TypeScript: exploring the realms of overloading and

This particular class is part of my code:

class Container<T>
{
    prop<K extends keyof T>(key: K): BehaviorSubject<T[K]>
    {
        return null;    // something
    }

    obj<K extends keyof T>(key: K): Container<T[K]>
    {
        return null;    // something
    }
}

I am utilizing it in the following manner:

interface Obj
{
    id: number;

    employee: {
        id: number;
        name: string;
    }
}

let container: Container<Obj>;
let id = container.prop('id');  // BehaviorSubject<number>
let employee = container.obj('employee');   // Container<{ id: number; name: string; }
let employeeName = employee.prop('name');   // BehaviorSubject<string>

Now, I desire to achieve similar behavior (variable types specified above) but I wish to use identical function names for both prop and obj. My goal is to have an overload that adjusts the returned type based on the property type.

Is this achievable in TypeScript?

Answer №1

If my comprehension is correct, you have the ability to implement something along these lines:

class Box<E> {
    private content: E;

    ...

    fetch<K extends keyof E>(key: K): Box<E[K]> | BehaviorSubject<E[K]> {
        let data = this.content[key];

        if (typeof data === "number" || typeof data === "string" || typeof data === "boolean") {
            // return a BehaviorSubject
        } else {
            // return a Box
        }
    }
}

The challenge arises when using this Box.fetch, because you will need to provide type assertions:

let userID = box.fetch("id") as BehaviorSubject<number>;
let person = box.retrieve("person") as Box<{ id: number; name: string; };

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

Alter the class based on the incoming string from the rxjs stream

I have a stream that outputs strings, and based on these strings I want to apply certain classes to a specific tag: If the string is "ok", add class "fa-check" If the string is "loading", add classes "fa-spin" and "fa-spinner" If the string is "error", a ...

Error in Angular caused by ChartJS: TypeError, inability to access property '_model' because it is null

I am currently working on a project that involves showcasing real-time data in a ChartJS graph. The data is retrieved from an external web server, and I have managed to store the data in 6 arrays (which are constantly changing) with each array containing 1 ...

Invoke the built-in matcher within a Playwright custom matcher

I am in the process of implementing a custom matcher for Playwright based on the information provided in the official documentation on extending expect. In a similar vein to this unanswered discussion, my goal is to invoke an existing matcher after modifyi ...

What is the best way to pass a state within a route component in react-router?

... import { useNavigate, NavigateFunction } from "react-router"; ... function Form(): JSX.Element { const navigateToCountry = (country: string) => { // Code to navigate to country page with the given country } const [selectedCount ...

typescript decorator implemented on a class that is nested within another class

Is it possible to decorate a nested property within a class? Let's explore with an example: function log(name: string = 'DecoratedProp') { return function logHandler(target: any, field: any) { // get the key ...

Guide to sending jQuery data back to main class in TypeScript

Hi everyone, I'm diving into the world of typescript and JQuery. I have a simple question. In my typescript class called DatePicker, I am calling a function. Here's a snippet of the code: Class DatePicker { private pickerData; public update( ...

Tips for receiving an array input in a GraphQL resolver

My query variables contain an array of strings that I need to use as the ids parameter inside my resolver. Below is the relevant code snippet. People.resolver.ts import { Resolver, Query, Mutation, Args, } from '@nestjs/graphql'; import { Peopl ...

The problem with Typescript's RXJS `distinctUntilChanged` arises when the strictness of the parameter is set to undefined

The code snippet provided below is not functioning as expected: let source: Observable<{ key: number }> = of({ key: 123 }); source.pipe( distinctUntilChanged(undefined, v => v.key) ); Despite the existence of an alternative signature: export ...

What steps can be taken to resolve the error message "Property does not have an initializer and is not definitively assigned in the constructor"?

I'm encountering an issue with these classes. I want to utilize the doSomething() method that is exclusive to class B without having to type cast it each time. However, when I specify property a to be of type B, it gives me an error saying it's n ...

Submitting a form that includes an <input type="file"/> in Angular 2: Best Practices

media.html <form #form="ngForm" (ngSubmit)="uploadFile(form.value)"> <input type="file" ngControl="inputFile" /> <input type="text" ngControl="name"/> <button type="submit" >Upload</button> </form> media.ts uplo ...

React Native, TypeScript, and Expo are experiencing difficulty displaying images

While working on a CRNA project using Typescript, I've encountered a problem with resolving images properly. Despite following the documentation provided here, I am unable to get the images to display correctly. Upon attempting to build for both IOS ...

Encountering a Typescript Type error when attempting to include a new custom property 'tab' within the 'Typography' component in a Material UI theme

Currently, I am encountering a Typescript Type error when attempting to add a custom new property called 'tab' inside 'Typography' in my Material UI Theme. The error message states: Property 'tab' does not exist on type &apos ...

Experimenting with Date Object in Jest using Typescript and i18next

I have included a localization library and within my component, there is a date object defined like this: getDate = () => { const { t } = this.props; return new Date().toLocaleString(t('locale.name'), { weekday: "long", ...

Steps for converting an object of the Map type to a string

class sample{ title : string items : Map<string,string> =new Map() constructor(){ this.title='Sunny' this.items.set('fruit','Apple') } } var s = new sample() console.log(s) console.log(JSO ...

What is the best way to declare a class as global in TypeScript without repeating code?

Is it possible to define a global class in TypeScript without repeating code? The following approach doesn't seem to work: declare global { class A { hi() { return "hi" } } } export {} As a result, I had to resort to repeated code usage. Yo ...

What is the best way to retrieve and showcase data in NextJs version 13 and beyond?

Being new to NextJS, my question may seem trivial but I'd appreciate your patience. Essentially, my goal is to fetch data from a database and display it on the page upon the initial render. To achieve this, I am utilizing the useEffect and useState ho ...

Tips for instantiating a class with another class as a variable?

When using typescript, I am passing an entire class as a reference MyClass to a function. How can I create a new instance of that class within the function? export class MyClass { } createClass(MyClass); function createClass(classReference) { const c ...

Is it possible to define an object literal type in typescript that permits unspecified properties?

I am looking to make sure that an object argument has all the necessary properties, while also allowing for additional properties. For instance: function verifyObject(input: { key: string }) : number { return input.key; } verifyObject({ key: 'va ...

Switching from dark mode to light mode when reloading or navigating to a new page

Hello everyone. I've successfully implemented a dark mode toggle on my website, but I'm facing an issue where the mode resets whenever I navigate to a new page or refresh the current page. Can anyone help me figure out how to prevent this from ...

Error TS2339: The 'email' property is not found in the 'FindUserProps' type

interface FindUserEmailProps { readonly email: string } interface FindUserIdProps { readonly id: string } type FindUserProps = FindUserEmailProps | FindUserIdProps export const findUserByEmail = async ({ email }: FindUserProps): Promise<IUser&g ...