Using Typescript Generics: Assigning Types Based on Object Properties

I am working with a Container class that accepts a dynamic object through its constructor. This dynamic object contains multiple classes, and I need to assign one or more of those classes to a property in the Container without sacrificing type safety.

Here's what I have attempted so far. The error message I'm encountering is

Property 'bbb1' does not exist on type 'A | B'.

If you want to check out the code and play around with it, feel free to visit this Playground

class A {
  aaa1 = "aaa1"
  aaa2 = "aaa2"
}

class B {
  bbb1 = "bbb1"
  bbb2 = "bbb2"
}

class Container<T> {
  all: T;
  target: T[keyof T];
  constructor(resources: T) {
    this.all = resources;
    this.target = resources["b" as keyof T];
  }
}

const obj = { a: new A(), b: new B() };
const container = new Container(obj);
console.log(container.target.bbb1) // Error

If you have any suggestions on how to approach this issue, I would greatly appreciate your input! Thank you.

Answer №1

class X {
  xxx1 = "xxx1";
  xxx2 = "xxx2";
}

class Y {
  yyy1 = "yyy1";
  yyy2 = "yyy2";
}

class Holder<T, K extends keyof T> {
  all: T;
  key: K;
  target: T[K];
  constructor(data: T, id: K) {
    this.all = data;
    this.key = id;
    this.target = data[id];
  }
}

const objects = { x: new X(), y: new Y() };
const box = new Holder(objects, "y");
console.log(box.target.yyy1); // No issue
console.log(box.Key); // "y"

implement a generic constraint K to signify the identifier of the information object.

Answer №2

Here is the revised solution. I made a few adjustments while maintaining type safety to prevent the error from occurring.

class X {
  xxx1 = "xxx1"
  xxx2 = "xxx2"
}

class Y {
  yyy1 = "yyy1"
  yyy2 = "yyy2"
}

class Box<S> {
  set: S;
  focus: S[keyof S];
  constructor(contents: S) {
    this.set = contents;
    this.focus = contents["c" as keyof S] ? contents["c" as keyof S] : contents["d" as keyof S];
  }
}

const object = { c: new X(), d: new Y() };
const box = new Box(object);

if (box.focus instanceof Y) {
  console.log(box.focus.yyy1)
} else if (box.focus instanceof X) {
  console.log(box.focus.xxx1)
}

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

Tips for effectively narrowing the `undefined` type

Why am I getting this error message? const func = (a: unknown) => { if (a && typeof a === 'object' && 'b' in a) { a.b; } }; The error message I'm receiving is: Property 'b' does not exist on ty ...

Angular 4 - Error: Unable to call this.changeHook as it is not a function

![image or error ]1Encountering a strange issue in my Angular 4 application. When I type in input text boxes, an error message TypeError: this.changeHook is not a function appears in the console. I'm struggling to understand the cause of this error. A ...

Error: The identifier HTMLVideoElement has not been declared

Encountering an issue while attempting to build my Angular 9 Universal project for SSR: /Users/my-project/dist/server.js:28676 Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:type", HTMLVideoElement) ReferenceError: HTMLVideoElem ...

Customizable column layout in react-grid-layout

I am looking to implement a drag and drop feature in which users can place items into a grid without fixed columns. The goal is that if an item is dragged from outside the grid boundaries and dropped to the right (an empty area), the grid will automaticall ...

Unable to find solutions for all parameters of the TemlComponent: (?). encountering a syntax error (compiler.js:1016)

As a beginner in Angular, I'm struggling to pinpoint the error in my code and understand why I'm encountering this issue. The error message reads: "Can't resolve all parameters for TemlComponent: (?). at syntaxError (compiler.js:1016)." To ...

When using a Redux action type with an optional payload property, TypeScript may raise complaints within the reducer

In my react-ts project, I define the following redux action type: type DataItem = { id: string country: string population: number } type DataAction = { type: string, payload?: DataItem } I included an optional payload property because there are tim ...

Autocomplete feature shows usernames while storing corresponding user IDs

I am looking to enhance the autocomplete functionality in my application while also ensuring that the selected user ID is stored in the database. Specifically, I want the autocomplete feature to display user names for selection purposes, but instead of re ...

When activating SSR in the Urql client, I encountered the following unexpected error: Server HTML should not include an <a> within a <div>

Unexpected Error Encountered while Rendering HTML at div at Styled(div) (Emotion Element) at div at Styled(div) (Emotion Element) at Flex (Chakra UI) at NavBar (Navigation Bar) at Index (Homepage) at withUrqlClient(Index) (Urql Client) at ColorModeProvider ...

Create categories for static array to enable automatic suggestions

I have a JavaScript library that needs to export various constants for users who are working with vscode or TypeScript. The goal is to enable auto-complete functionality for specific constant options. So far, I've attempted to export a Constant in th ...

Incorporating TypeScript into a project originally developed in JavaScript

I'm considering using TypeScript to write code for a JavaScript project. I've come to appreciate the benefits of TypeScript and am especially interested in using it for our AngularJS 1.5 project, which we plan to migrate soon. As I'm new to ...

Undefined values do not function properly with discriminated unions

In my React component, there are two props named required and fallback. The type definition for these props is as follows: type Props = | { required? : true | undefined, fallback : React.ReactNode } | { required? : false, fallback? : React.Rea ...

Modify visibility within a subclass

Is there a way to modify property visibility in a child class from protected to public? Consider the following code snippet: class BaseFoo { protected foo; } class Foo extends BaseFoo { foo = 1; } new Foo().foo; It seems that this change is pos ...

What is the best way to start a class instance within a stateless function component in React?

When following a stateful pattern, my usual approach is to initialize a helper class in the constructor and consume its methods in component lifecycle methods, as shown in the example below: class StatefulComponent extends Component { constructor(props) ...

OCI: Predict expenses based on a selection of virtual machines

Seeking to determine the anticipated cost of a selection of instances within OCI utilizing the TypeScript SDK. Oracle offers a tool called Cloud Cost Estimator for configuring and dynamically displaying cost estimates. Is it possible to achieve this throug ...

Is it considered beneficial to use Observable as a static class member?

Lately, I have been diving into a new Angular project and noticed that the common way to share state between unrelated components is by using rxjs Subject/BehaviorSubject as static members within the class. For instance: export class AbcService { privat ...

Angular does not recognize the boolean variable

Within my Angular component, I have declared two boolean variables: editingPercent: boolean = true; editingCap: boolean = false; In the corresponding HTML file, there is a checkbox that updates these variables based on user input: checkedChanged(e) { ...

Merging Type-GraphQL and Typegoose through a Variety of Decorators

Using a combination of Type-GraphQl and Typegoose, I aim to streamline my data definitions by consolidating them into one source for both GraphQL schemas and Mongoose queries. Is it feasible to merge the two libraries in a way that allows me to describe bo ...

Encountered an issue with running tests in vscode-test - runTests function throwing

Setting up tests for my vscode extension for the first time and encountering an issue. I copied and pasted the example from code.visualstudio's /working-with-extensions/testing-extension. However, I'm facing an error when trying to call runTest ...

Attempting to render a string in React is causing an error because the type 'void | undefined' is not compatible with the type 'ReactNode'

I have developed a custom hook that retrieves an array of objects called navMenuOptions, along with a function that can return a specific navMenuOption based on a string input. export const useNavMenuOptions = () => { const intl = useIntl() const p ...

Encountering issues with pipes and ngModel functionality in Angular causing errors

I have a unique custom dropdown feature that binds the selected dropdown value to an input field in my reactive form using ngModel. I have also implemented a mask on the input fields using a pipe. Here is all the relevant code for this functionality: HTML ...