Declaring multiple keys for enums in Typescript

Incorporating a Text component in Typescript offers various type options, such as:

<Text type='h2'>Hello World</Text>
.

Utilizing a styles object with these types as keys allows for deriving the appropriate styles. However, there should be flexibility for multiple type possibilities.

import React from 'react'
import { colors } from '../../config'

const getKeyValue = <U extends keyof T, T extends object>(key: U) => (obj: T) => obj[key]

const styles = {
  h1: {
    fontSize: "46px",
    lineHeight: "64px",
    fontWeight: 300,
  },
  h2: {
    fontSize: "34px",
    lineHeight: "48px",
    fontWeight: 300,
  },
  // Additional style objects...
}

interface Style {
  fontSize: string;
  lineHeight: string;
  fontWeight: number;
}

// Interfaces and Props declaration...

const Text = ({ children, type, color = colors.darkGrey, ellipsis = false, fontWeight }: Props) => {

  const style = {
    ...getKeyValue<keyof Styles, Styles>(type)(styles),
    color,
    minHeight: 25, // Height to be modified
    textOverflow: ellipsis ? 'ellipsis' : 'none',
    overflow: ellipsis ? 'hidden' : 'none',
    whiteSpace: ellipsis ? 'nowrap' : 'none',
  } as React.CSSProperties

  if (typeof fontWeight !== 'undefined') {
    style.fontWeight = fontWeight
  }

  return <div style={style} >{children}</div>
}

export default Text


The current implementation requires repeated declaration of style object keys:

  • In the styles object itself
  • In the Styles interface
  • In the declaration of type type

This redundancy can be optimized, but figuring out an improved approach is challenging due to my limited experience with TypeScript. Any suggestions for a more concise and efficient solution are welcome!

Answer №1

To determine the Styles and type based on the inferred type of the styles constant, we utilize the following approach: By utilizing the typeof to obtain the type of the constant and using keyof to retrieve its keys. Subsequently, we can leverage Record to create the Styles type (which is essentially a type with a set of keys that all share the same type).


type StyleType = keyof typeof styles
type Styles = Record<StyleType, Style>

Check out this Playground Link

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

Encountering a script error when upgrading to rc4 in Angular 2

After attempting to update my Angular 2 version to 2.0.0.rc.4, I encountered a script error following npm install and npm start. Please see my package.json file below "dependencies": { "@angular/common": "2.0.0-rc.4", "@angular/core": "2.0.0-rc.4", ...

What is the best way to elegantly extract a subset array from an array of objects?

Imagine you have the following array of objects: var myObject = [ {A:1, B:2, C:3}, {A:4, B:5, C:6}, {A:7, B:8, C:9}, ] How would you efficiently retrieve a subset with the Y values from this array? var subset = [ B:2, B:5, B:8 ] ...

Error TS7027: Unreachable code was identified in TypeScript

sortArrayDate(arrayToSort, arrayDateKey, order) { if (order === 'ascending') { arrayToSort.sort(function(a, b){ if (a[arrayDateKey] === '' || a[arrayDateKey] === null) { return 1; } if (b[arra ...

An element from an array of typescript items

My current challenge involves working with arrays. Here is an example of the array I am dealing with: Array[{id:0,name:"a"},{id:1,name:"b"}...] In addition to this array, I have another array called Array2. My goal is to extract items from Array where th ...

The close button in Angular 4 is unresponsive until the data finishes loading in the pop-up or table

Having trouble with the Close button in Angular 4 popup/table The Pop Up is not closing after clicking anywhere on the screen. I have added backdrop functionality so that the pop-up closes only when the user clicks on the close icon. However, the close i ...

Having trouble accessing property '0' of undefined in angular

Below is the code I am currently working on. My goal is to enable editing of the table upon click, but I encountered the error mentioned below. Could someone kindly explain why this is happening and suggest a workaround? <tbody> <tr *ngFor="l ...

Guide to showcasing JSON Array in an HTML table with the help of *NgFor

Struggling to showcase the data stored in an array from an external JSON file on an HTML table. Able to view the data through console logs, but unable to display it visually. Still navigating my way through Angular 7 and might be overlooking something cruc ...

What is the best way to create a case-insensitive sorting key in ag-grid?

While working with grids, I've noticed that the sorting is case-sensitive. Is there a way to change this behavior? Here's a snippet of my code: columnDefs = [ { headerName: 'Id', field: 'id', sort: 'asc', sortabl ...

Ensure that the click event on the HTML element is only triggered one time

In my application, I have the following code snippet. The issue is that this code resides in each table column header. Therefore, whenever I click on a mat-select option, new values are generated and used in an *ngFor loop for mat-option. The problem aris ...

What steps should I take to modify the date format to "dd / mm / yy"?

When using 'toISOString ()' in JavaScript, it appears as shown in photo 2. How can I modify this format? Note: I am working with AngularJs. Image 1 is located in list.component.ts Additional documents: Image 1 Image 2 Image 1: formatDate(e) ...

Issue with Angular 11: Unable to bind to 'ngForOf' as it is not recognized as a valid property of 'tr' element

My issue lies with a particular page that is not functioning correctly, even though it uses the same service as another working page. The error seems to occur before the array is populated. Why is this happening? I appreciate any help in resolving this p ...

index.ts import statement results in undefined value being returned

I have a simple file structure set up like this: src index.ts services my-service.ts In index.ts, I have the following code: export const a = 3 And in my-service.ts, I use the following import statement: import { a } from '../index' consol ...

Incorporate elements into an array using TypeScript's map method

I'm working with a JS Map that's defined as let mappy = new Map<string, string[]>() I want to add elements to the array using the key. I could do it like this: mappy.set(theKey, mappy.get(theKey).push('somevalue')); This seems li ...

Combine multiple arrays containing observables into a unified array

I am facing the challenge of flattening a nested Observable into a single observable array. The Observable looks like this: Observable<Observable<any[]>[]> values; The inner arrays have the following structure: [ {id: 0, name: 'a'} ...

Discover the highest value within an array of objects, along with any numerical object attributes that have a value greater than zero

Considering an array of objects structured as follows: [{ "202201": { "WO": 900, "WS": 0, "SY": 0.915, "LY": 0.98, "CT": 75 }, "202202" ...

Issue with Vite React TypeScript XLSX: An Uncaught SyntaxError occurred as the module '/node_modules/.vite/deps/xlsx.js' does not export a feature named 'default'

While attempting to integrate the xlsx library into a project using vite, reactjs, and typescript, I encountered the following error: Uncaught SyntaxError: The requested module '/node_modules/.vite/deps/xlsx.js?v=823b22a3' does not provide an e ...

Utilizing Angular service in a separate file outside of components

In my library file product.data.ts, I have a collection of exported data that I need to update based on a value returned by a featureManagement service. Our team regularly uses this service and includes it in the constructor of any component using standard ...

What is the syntax for declaring a list of JSON objects in TypeScript?

I've been attempting to implement something similar to the following: interface IUser { addresses: JSON = []; } Unfortunately, it doesn't seem to be working! I'm looking to store a list of nested JSON objects inside the addresses field, ...

What is the reason behind the inability to utilize page.locator within a page.waitForFunction?

Delving into Playwright for the first time, coming from a Cypress background where I am familiar with the cypress-wait-until function. I'm currently trying to wait until a specific number of DOM elements exist, and although I've found various so ...

Obtaining the identification of an element from a FormControl

Hello, I have an input selection with a label (value) and key (id). When I click on submit, I want to retrieve the key (id). <form (submit)="onSubmit(testForm)" [formGroup]="form"> <mat-form-field> <input matInput type ...