Property value derived from another property via a mapped type

I possess a type known as ElementCategory that comprises an array of elements with varying types.

Each element is equipped with numerous properties, including a type property of the type ElementType, which serves as an enum listing all available element types, and a variable data property dependent on the specific type of the element.

A mapped type dubbed ElementsData is in place to ideally receive the element type and return the corresponding data type exclusively for that specific element type (however, the code below doesn't exhibit this behavior):

 [Code Snippet]

My inquiry is: How can I ensure that the ElementType passed to the type property matches the one sent to ElementsData?

If you check out the Repro link I've generated to exemplify the issue. Hovering over the data property during element creation reveals it's not accurately detecting the data type based on the element type, as anticipated.

Note: Even after attempting to make 'Element' generic, I was obliged to incorporate a generic type annotation to the elements array, which didn't yield the intended outcome since forcing a single element type in the array wasn't my aim. Did I overlook something?

Answer №1

To create a comprehensive union of all potential combinations, you can achieve this by iterating through the ElementType enum.

type ScriptElement = {
    name: string
} & {
    [K in ElementType]: {
        type: K,
        data: ElementsData[K]
    }
}[ElementType]

If the type does not correspond to the data, an error will be flagged.


const ContentElementsCategory: ElementCategory = {
    name: 'Content',
    elements: [
        {
            name: 'Text',
            type: ElementType.Text,
            data: defaultElementsData[ElementType.Text],
        },
        {
            name: 'Picture',
            type: ElementType.Picture,
            data: defaultElementsData[ElementType.Picture],
        },
        {
            name: 'Rating',
            type: ElementType.Rating,
            data: defaultElementsData[ElementType.Text], // Error 
        },
    ],
};

Playground

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

combine two separate typescript declaration files into a single package

Can anyone help me figure out how to merge two typescript definition packages, @types/package-a and @types/package-b, into one definition package? package-a.d.ts [export package-a {...}] package-b.d.ts [exports package-b {...}] package-mine.d.ts [ export ...

An error occurs when attempting to use object mapping and the rest operator in a return statement due to

I've encountered a type mismatch error in my TypeScript project using Prisma while attempting to return an object with mapped properties in the getPool method. Let's take a look at the code snippet causing the issue: public async getPool({ id, v ...

Creating a specification for a type that lacks a specific concluding character

When utilizing TypeScript, you have the ability to create template literal types such as: type Paragraph = `${string}\n`; const paragraph: Paragraph = 'foo\n'; // valid const word: Paragraph = 'foo'; // invalid But can you d ...

Creating a Thrilling Triple Image Transformation on Hover using Material-UI

Here is a Codepen showcasing a triple hover effect on an image: Codepen I attempted to recreate this effect as a styled component in React Typescript using MUI and MUI Image, but encountered an error with my styling that is preventing it from working in m ...

When you extend the BaseRequestOptions, the injected dependency becomes unspecified

Implementing a custom feature, I have chosen to extend BaseRequestOptions in Angular2 to incorporate headers for every request. Additionally, I have introduced a Config class that offers key/value pairs specific to the domain, which must be injected into m ...

Improving DynamoDb Query Results with Type Hinting

In the following Typescript code, how can I specify which fields should be present in my Query Items Result? const request: DynamoDB.DocumentClient.QueryInput = { TableName: UnsubscriptionTokensRepository.TABLE_NAME, IndexName: 'TokenIndex&ap ...

Choosing a default selected value from a dropdown list with multiple editing options

When loading my "multiple edit" screen, I default the values as follows: private createFormGroupItem(item: ...): FormGroup { return this.formBuilder.group({ title: new FormControl(item.title, [Validators.required]), effectiveDate: new FormC ...

Transitioning Apollo Server from version 3 to version 4 within a next.js environment

Previously in v3, you could define "createHandler" like this: export default async (req, res) => { await startServer; await apolloServer.createHandler({ path: "/api/graphql", })(req, res); }; However, in v4, this is no longer possi ...

What is the best way to apply ngClass to style a JSON object based on its length?

Currently, I am working with a mat-table that displays data from a JSON object. My goal is to filter out all records with an ID of length 5 and then style them using ngClass in my HTML template. How can I achieve this? Below is the code I am working with: ...

Executing cypress tests with tags in nrwl nx workspace: A simple guide

Currently, I am working within a nrwl nx workspace where I have set up a cypress BDD cucumber project. My goal is to run cypress tests based on tags using nrwl. In the past, I would typically use the "cypress-tags" command to achieve this. For example: &q ...

Unlocking the potential of deeply nested child objects

I have a recursively typed object that I want to retrieve the keys and any child keys of a specific type from. For example, I am looking to extract a union type consisting of: '/another' | '/parent' | '/child' Here is an il ...

Tips for setting up a typeorm entity with attention to its nullable fields

How can I assign values to typeorm entities and insert them into the database? import { PricingPatternElement } from file const Element:PricingPatternElement = { displayOrder: 10, elementName: "test", createdAt : getCurrentDate(), createdBy: &qu ...

Dealing with TypeScript type conversion and D3.js error handling

Now, how can I go about solving this or typecasting it? import { useEffect, useState } from "react"; import { arc, pie, DSVRowArray, csv, PieArcDatum } from "d3"; const CSVURL = "https://gist.githubusercontent.com/mzs21/df0621d1 ...

Only map property type when the type is a union type

My goal is to create a mapping between the keys of an object type and another object, following these rules: Each key should be from the original type If the value's type is a union type, it should have { enum: Array } If the value's type is not ...

The JQuery signature does not include the necessary string context

We are in the process of transitioning legacy JavaScript code to TypeScript. In our current codebase, we have jQuery selectors that utilize a string as a context: $("example", "someId"). However, when converting this to TypeScript, the definition file JQu ...

The datatype 'string' cannot be assigned to the datatype '(token: string) => void'

Within my Angular2 application, I have a class that includes several properties which will be assigned values within components. @Injectable() export class Globals { private token: string; private authorization: string; private roleUser: boole ...

What are the distinctions between using getStaticPaths + getStaticProps and useRouter in NextJS?

I'm currently diving into the world of NextJS and finding myself puzzled by the distinctions between getStaticProps & getStaticPaths compared to utilizing useRouter().query. At this point, it appears to me that both methods serve a similar purpos ...

Experiencing a Typescript issue while trying to set a string as the state of a React component with a specified TS type

I've defined a state in my React component for a specific data type called Color. \\ state const [messageSeverity, setMessageSeverity] = useState<Color>('success'); \\ TS type export type Color = 'success&ap ...

Is there a way to create a stub for the given function using sinon?

Here is my test function: const customTestLibrary = require("./test"); describe("Initial Test", function() { it("should run the test function successfully", function(done) { customTestLibrary.execute(); done(); }); }); The te ...

Set the GridToolbarQuickFilter text box to have an outlined style in Material UI v5

How can I customize the appearance of the GridToolbarQuickFilter textbox, such as outlining it? Ideally, I would like to accomplish this through theme.tsx, but I am open to any suggestions. https://i.stack.imgur.com/H1Ojj.png I have experimented with var ...