A TypeScript export class that is created based on configuration parameters

As someone who has primarily worked with C#, TypeScript is a new and exciting challenge for me. I've been enjoying exploring what I can create quickly using Node/TypeScript. However, I've run into a syntax issue that I could use some help with. I have an interface that two concrete classes implement, and another module that exports one of these classes based on configuration.

fruit.ts

export interface Fruit {
  eat();
}

apple.ts

export class Apple implements Fruit {
  eat() { console.log('Eat apple'); }
}

banana.ts

export class Banana implements Fruit {
 eact() { console.log('Eat banana'); }
}

breakfast.ts

import { Fruit } from 'fruit';
import { Apple } from 'apple';
import { Banana } from 'banana';

const BreakfastType: typeof Fruit = config.appleForBreakfast ? Apple : Banana;   <-- Error

export { BreakfastType }

On paper, this setup seems like it should function correctly. After all, Apple and Banana are both "types of fruit," so declaring BreakfastType as "typeof Fruit" makes sense to me. However, TypeScript is throwing an error:

Fruit only refers to a type, but is being used as a value here

While this example might seem contrived, it reflects my current coding dilemma perfectly. Ultimately, I want the following code to be able to work:

import { BreakfastType } from 'breakfast';
let breakfastFood = new BreakfastType();    <-- create Apple or Banana based on config

If anyone has any suggestions, I would greatly appreciate your input!

Answer №1

There are a couple of issues to address here. Firstly, using typeof is not suitable for TypeScript types; it should only be used for JavaScript variables, classes, objects, and other non-TypeScript entities. Therefore, the line that follows should not include typeof Fruit:

const BreakfastType: Fruit = config.appleForBreakfast ? Apple : Banana;

However, another problem surfaces as TypeScript still throws an error about types:

Property 'eat' is missing in type 'typeof Apple' but required in type 'Fruit'
. Upon further investigation, it becomes apparent that specifying BreakfastType as above leads TypeScript to interpret it in a certain way:

It interprets BreakfastType as a variable of type Fruit, even though we attempt to assign Apple or Banana to it. These are actually classes, not instances of them. To resolve this, you can explicitly declare that BreakfastType is a class rather than an instance with new () => Fruit

const BreakfastType: (new () => Fruit) = config.appleForBreakfast ? Apple : Banana
const MyBreakfast = new BreakfastType() // MyBreakfast will now have the type Fruit

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

The Angular7 counterpart of the C# attribute decorator

I'm working with an API method that has an Authorize attribute to verify permissions. [Authorize(ReadIndexes)] public async Task<IActionResult> GetIndexes () { ... } Is there a similar way in Angular to implement permission checks so the API ...

Unable to retrieve shared schema from a different schema.graphql file within the context of schema stitching

In my project, I have a user schema defined in a file named userSchema.graphql; id: String! userName: String! email: String! password: String! } In addition to the user schema, I also have separate schema files for login and register functionalit ...

Why does TypeScript keep throwing the "No inputs were found in the config file" error at me?

Why am I receiving the No inputs were found in config file error from TypeScript? I have set up my tsconfig.json in VS Code, but the error occurs when I try to build it. The terminal displays: error TS18003: No inputs were found in config file '/Use ...

What is the best way to associate an HTTP request response with a specific object in TypeScript?

I'm currently learning Angular, TypeScript, and RxJS. I have an HTTP request that retrieves a JSON response. Within this JSON response, there is data that I need to use to create a specific object. Let's assume that the object I want to create lo ...

Utilizing TypeScript for enhanced Chrome notifications

I am currently developing a Chrome app using TypeScript (Angular2) and I want to implement push notifications. Here is the code snippet for my notification service: import {Injectable} from 'angular2/core'; @Injectable() export class Notificati ...

Using Kendo's Angular Grid to link data sources

I'm currently facing a minor issue with the Kendo Grid for Angular. My attempt to bind data after fetching is resulting in the following error: ERROR TypeError: Cannot read properties of undefined (reading 'api') This indicates that this. ...

Tips for maintaining data reactivity while transmitting it to a function

Consider the following setup for my component: <script setup lang="ts"> interface FileMetadata { owner: string, location: string, size: number, // And around 50 mores... } interface File { fileName: string, metadata: FileMetada ...

Error: Unable to perform operation on undefined object when trying to map over 'reminder' object

I've been struggling with my reminder-list.tsx file. No matter how many times I try to fix it, I always end up failing. Can someone help me figure out how to resolve this issue? Every time I run the code, I get the TypeError: undefined is not an obje ...

Encountering an error with loading in Angular may require a suitable loader

I am currently working on integrating an AWS QuickSight dashboard into an Angular application. For implementation in Angular, I am referring to the following URL: https://github.com/awslabs/amazon-quicksight-embedding-sdk Could someone provide me with sa ...

Using React Router DOM's History Object in Typescript Triggers an Error

I am encountering an issue with a stateless component that receives the History object from react-router-dom and passes it down to a stateful component through props. Typescript is raising an error when trying to pass the history object as a prop. Below a ...

Can anyone provide guidance on setting up a TypeScript service worker in Vue 3 using the vite-plugin-pwa extension?

I am looking to develop a single-page application that can be accessed offline. To achieve this, I have decided to implement a PWA Service Worker in my Vue webapp using TypeScript and Workbox. I found useful examples and guidance on how to do this at . Ho ...

Fixing 404 Errors in Angular 2 Due to Component Relative Paths in SystemJS-Builder

I recently posted this on https://github.com/systemjs/builder/issues/611 My goal is to bundle my Angular 2 rc 1 application using systemjs-builder 0.15.16's buildStatic method. In my Angular component, there is a view and one or more external stylesh ...

Conditional type/interface attribute typing

Below are the interfaces I am working with: interface Movie { id: number; title: string; } interface Show { title: string; ids: { trakt: number; imdb: string; tmdb?: number; }; } interface Props { data: Movie | Show; inCountdown ...

What is the best way to transform this JSON data into an array of key-value pairs in JavaScript?

Dealing with nested JSON data can be challenging, especially when trying to extract key-value pairs efficiently. If anyone has suggestions on how to simplify this process and improve readability, please share your insights. The goal is to transform the ne ...

mat-autocomplete Show user-friendly names while storing corresponding IDs

I am currently utilizing a Mat-autocomplete feature that allows for loading a list of "users". Within the autocomplete functionality, I aim to exhibit the username while retaining the selected user ID value. Originally, I had: this.allFruits = val.map( ...

Searching for a value within an array of objects in Typescript/Vue 3. The objects are of an unknown data type

Is there a way to fix this TypeScript error? To provide some background, I am working with the Vue 3 Composition API where I need to use the result to determine if a default option value should be displayed as <option ... selected v-if="!isMatch&qu ...

Assign object properties to a constant variable while validating the values

When receiving the features object, I am assigning its values to constants based on their properties. const { featureCode, featureSubType, contentId, price, family: { relationCountsConfig: { motherCount, fatherCount, childrenCount }, max ...

Presenting information on the user interface

Recently, I have been working on an API endpoint that retrieves comments by ID, using the endpoint get/comments/:id. When I tested this endpoint using Postman, the response I received was as follows: { "id": 401478, "page": 1, "results": [ ...

Property does not exist when dispatching in React Redux within componentDidMount

Currently, I am navigating my way through my initial project using React + Redux and have hit a few roadblocks while attempting to dispatch a function in the componentDidMount section. I tried to emulate the Reddit API example project from the Redux docume ...

Using Typescript to replicate Object.defineProperties

Is there a way to emulate Object.defineProperties from JavaScript in Typescript? I am interested in achieving something similar using the syntax of Typescript: Object.defineProperties(someObject.prototype, { property: {get: function() { return v ...