Tips for adding an extensive collection of fixed attributes to a function using Typescript

I am attempting to write a function that includes a lengthy list of static strings attached as properties, all returning the property as a string value:

const arr = ["a", "b", "c"]; // there are around 140 items in the actual list

const f = (tag: string | undefined) => tag;

arr.forEach(key=> {
  f[key] = f(key)
})

console.log(f.a) // "a"
console.log(f.b) // "b"
console.log(f.c) // "c"
console.log(f.d) // undefined

Issues:

Element is implicitly an 'any' type because expression of type 'string' cannot be used to index type '(tag: string) => string'. No index signature with a parameter of type 'string' was found on type '(tag: string) => string'.
Property 'a' does not exist on type '(tag: string) => string'.
Property 'b' does not exist on type '(tag: string) => string'.
Property 'c' does not exist on type '(tag: string) => string'.
Property 'd' does not exist on type '(tag: string) => string'.

Typescript Playgound


Answer №1

To start, define the array of constant properties using as const to ensure the type is ['x', 'y', 'z'] instead of just string[].

const properties = ['x', 'y', 'z'] as const;

Next, extract these string constants as a union of string literals by accessing the type of the array and indexing it by number.

type Values = (typeof properties)[number] // 'x' | 'y' | 'z'

Now, declare the function type and the constant properties separately.

type FunctionType = (value: string | undefined) => string | undefined
type StaticProperties = { [item in Values]: string }

Combine these types by intersecting them to include the static properties in the function type.

type FunctionWithStatic = FunctionType & StaticProperties

If you try to create a function labeled as FunctionWithStatic without defining the static properties, Typescript will throw an error as those properties need to be specified to meet the type requirements. To resolve this, generate the static properties as a separate object.

const staticProps = properties.reduce((result, prop) => {
  result[prop] = prop;
  return result
}, {} as StaticProperties)

Subsequently, merge these generated static properties with the function using Object.assign().

const f: FunctionWithStatic = Object.assign(
  (val: string | undefined) => val,
  staticProps
)

Now, when utilizing the function, you should see the expected behavior:

f.x // returns: string
f.y // returns: string
f.z // returns: string

f.w // type error, as the static property is not part of the original `properties` array

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

TypeScript does not verify keys within array objects

I am dealing with an issue where my TypeScript does not flag errors when I break an object in an array. The column object is being used for a Knex query. type Test = { id: string; startDate: string; percentDebitCard: number, } const column = { ...

What is the significance of `new?()` in TypeScript?

Here is a snippet of code I'm working with in the TypeScript playground: interface IFoo { new?(): string; } class Foo implements IFoo { new() { return 'sss'; } } I noticed that I have to include "?" in the interface met ...

Angular: Exploring the most effective strategies for optimizing code within the ".subscribe()" method

Imagine having a component structured like this The Initial Code: import { HttpClient } from '@angular/common/http'; import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: `<pre>{{ ...

Encountering an error "Property is used before its initialization" in Angular 10 when attempting to input an object into a template

My code includes a class: import * as p5 from 'p5'; export class Snake{ constructor() { } sketch = (p: p5) => { p.setup = () => { ... } } } To instantiate this class in app.component, I do the follow ...

Adjust the size of a map on an HTML page after it has

Currently, I am utilizing Angular 2 to create a simple webpage that includes a Google 'my map' displayed within a modal. <iframe id="map" class="center" src="https://www.google.com/maps/d/u/0/embed?mid=1uReFxtB4ZhFSwVtD8vQ7L3qKpetdMElh&ll ...

Changing the button class during an event in Angular 4

In the process of creating an MCQ test, I am looking to implement a feature where selected button options are highlighted in green upon clicking. While I have successfully implemented this feature using Angular 1, I am facing challenges in converting it to ...

Tips for integrating the react-financial-charts library into your React and JavaScript project

While exploring the react-financial-charts library, I discovered that it is written in TypeScript (TS). Despite my lack of expertise in TypeScript, I am interested in using this library in my React+JS project due to its active contributions. However, I hav ...

Creating a React Native project without the use of TypeScript

Recently I dived into the world of React Native and decided to start a project using React Native CLI. However, I was surprised to find out that it uses TypeScript by default. Is there a way for me to create a project using React Native CLI without TypeS ...

What is the best way to make the first option blank?

Is there a way to have the select field start with an empty value instead of the default dollar sign? The demonstration can be found at https://codesandbox.io/s/material-demo-forked-xlcji. Your assistance in achieving this customization would be greatly a ...

Tabulate the number of items in an array based on the month and

I have received JSON data with dates indicating the creation time of multiple parcels. I want to analyze this data and calculate the total number of parcels created in each month. I am new to this process and unsure about which thread on Stack Overflow can ...

Find out if a dynamically imported component has finished loading in Nextjs

Here is a simplified version of my current situation import React, { useState } from 'react'; import dynamic from 'next/dynamic'; const DynamicImportedComponent = dynamic(() => import('Foo/baz'), { ssr: false, loading ...

Unable to link to 'amount' because it is not a recognized attribute of 'ng-wrapper'

I recently made some changes to my code and now I'm encountering the error message "Can't bind to 'count' since it isn't a known property of 'ng-container'" Instead of having both the notification component and notificat ...

When using the e.target.getAttribute() method in React, custom attributes may not be successfully retrieved

I am struggling with handling custom attributes in my changeHandler function. Unfortunately, React does not seem to acknowledge the custom "data-index" attribute. All other standard attributes (such as name, label, etc.) work fine. What could be the issu ...

When attempting to import the image path from a JSON file, a ReferenceError occurs stating that the data variable is not

I'm currently attempting to iterate through image paths in a JSON file and display them in a browser using the "img" tag. While hardcoded values work perfectly fine, I encountered an issue when trying to switch to a variable as outlined in this post: ...

Typedoc: only export contents from a particular file are documented

Currently, I am working on developing two npm packages: https://github.com/euberdeveloper/mongo-scanner https://github.com/euberdeveloper/mongo-cleaner My goal is to create documentation for these packages using Typedoc. The main file is index.js p ...

Node.js is known for automatically adding double quotes to strings. However, is there a way to eliminate them?

After creating a unit test, I noticed that both logics I used led to the same issue. Logic 1: describe('aresFileCopier', () => { test('log error', async () => { await registerDB('ares-test', { client: ' ...

Using React and TypeScript to pass member variables

My component Child has a member variable that can change dynamically. While I am aware of passing props and states, is there a more elegant solution than passing member variables through props or other parameters? class Child extends React.Component< ...

Error in Mocha test: Import statement can only be used inside a module

I'm unsure if this issue is related to a TypeScript setting that needs adjustment or something else entirely. I have already reviewed the following resources, but they did not provide a solution for me: Mocha + TypeScript: Cannot use import statement ...

Is it possible to apply filters to individual columns in a dynamic mat table using Angular?

Does anyone know how to add a filter for each dynamic column in an Angular Material table? I've only found solutions for static headers, but my table headers are constantly changing. I'm looking for something similar to this example: https://i.st ...

Navigating Through Angular Components

I have a layout with 3 components arranged like this: <app-header></app-header> <app-body></app-body> <app-footer></app-footer> However, I want to change the positioning of the footer and body as shown below: <app-he ...