Can we utilize the elements in Array<keyof T> as keys in T?

Hello, I am trying to develop a function that accepts two parameters: an array of objects "T[]" and an array of fields of type T. However, I am encountering an issue when I reach the line where I invoke el[col]

    Argument of type 'T[keyof T]' is not assignable to parameter of type 'string'.
  Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'string'.
    Type 'T[string]' is not assignable to type 'string'.(2345)

The code snippet in question is as follows:

interface user {
  name: string;
  age: number;
  lastname: string;
}

const data: user[] = [
  {
    name: 'foo',
    age: 21,
    lastname: 'bar',
  },
  {
    name: 'foo',
    age: 21,
    lastname: 'baz',
  },
  {
    name: 'foo',
    age: 21,
    lastname: 'bax',
  },
];

function printLastName<T>(data: T[], cols: Array<keyof T>) {
  data.forEach((el) => {
    let msg = '';
    cols.forEach((col) => {
      msg = msg.concat(el[col]);
    });
    console.log(msg);
  });
}

printLastName(data, ['name', 'lastname']);

Answer №1

The issue arises from the fact that the variable T can have any value type, including objects. When you try to use data[index][col] as a string without converting it properly, it results in an error. This is why String(el[col]) was successful in resolving the problem. Alternatively, using msg.concat('' + el[col]); or msg += el[col]; would also yield the desired outcome.

Answer №2

If you want to ensure types work correctly, one option is to have T extend an array.

Then, you can utilize keyof T[number] or simply T[0], as all elements are consistent.

For example:

interface person {
  name: string;
  age: number;
  lastname: string;
}

const dataset: person[] = [
  {
    name: 'John',
    age: 30,
    lastname: 'Doe',
  },
  {
    name: 'Jane',
    age: 25,
    lastname: 'Smith',
  },
  {
    name: 'Bob',
    age: 45,
    lastname: 'Johnson',
  },
];

function displayLastName<T extends any[]>(data: T, columns: Array<keyof T[number]>) {
  data.forEach((element) => {
    let message = '';
    columns.forEach((col) => {
      message = message.concat(element[col]);
    });
    console.log(message);
  });
}

displayLastName(dataset, ['name', 'lastname']);
//displayLastName(dataset, ['name', 'error']); <-- Produces an error

TS 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

Retrieving a Date object from a JSON response

Hey there, I have a situation where I'm trying to convert a JSON response into a date object in order to display it in a different format. Here's the JSON response I'm working with: responseData: [{"id":10,"createdDate":"1 Sep, 2014 12:48:5 ...

Is there a way to use JQuery/AJAX to extract the selected values from all drop-down menus within a designated container?

With the help of JavaScript, I am dynamically creating dropdown lists under dvContainer. My goal is to retrieve the selected values of all select elements within that container. Below is the HTML code generated through JavaScript: <div id="dvContai ...

retrieving the file directory from a folder with the help of ajax

I am having trouble retrieving a list of files from a specific URL that lists files inside a folder: https://i.sstatic.net/VH22b.png In order to obtain this list of files using JavaScript, I have written the following code: $.ajax({ url: &ap ...

Is there a way to automatically scroll to the last dynamically added div?

Within the chat.html file, I have included a div tag and implemented a script that dynamically adds rows to the div when a button is clicked. In another file named list.html, I have inserted an iframe tag with the src attribute pointing to chat.html. Howev ...

Guide on adding a button to a mat-table in Angular

I am looking to add a delete button or an Angular trash icon to a mat-table in an Angular application. Can anyone guide me on how to achieve this? Here is my current table code: <mat-table #table [dataSource]="ELEMENT_DATA"> <ng-container cdk ...

Tips for utilizing the async.js library in combination with the await keyword?

Currently, I am working on integrating the async library to continuously poll an API for a transaction until it is successful. router.get('/', async function (req, res) { let apiMethod = await service.getTransactionResult(txHash).execute(); ...

Tips for incorporating asynchronous page components as a child element in next.js?

Utilizing the latest functionality in next.js for server-side rendering, I am converting my component to be async as per the documentation. Here is a simple example of my page component: export default async function Home() { const res = await fetch( ...

Modify HTML text using conditional CSS without JavaScript

Apologies for asking such a beginner question, but I've searched high and low for a similar post, to no avail. Here's my query: I have a paragraph text in my HTML code that I want to automatically replace with new text when I click a specific B ...

Is it possible to verify the necessary node_modules for the project?

Is there a more efficient method to identify and remove unnecessary node_modules packages from my create-react-app project, rather than individually checking all utilized packages and their dependencies? I'm hoping to trim down the project's siz ...

Creating visually appealing Highcharts.js visualizations for both mobile and desktop devices

Has anyone had success implementing a responsive design with Highcharts to ensure charts look great on both mobile and desktop screens? By default, Highcharts do adjust when resizing the browser window, but sometimes the X-axis can become cluttered by tic ...

Why won't Node.js let me redirect to my error page?

I've been putting together my newsletter project with the Mailchimp API, everything seems to be working fine except for when I try to redirect to a failure page if the status code is not 200. The browser shows an error message saying 'localhost r ...

Implementing JSON parsing in an ESP32 application using AJAX script

Currently, I am engrossed in a project that involves utilizing ESP32. I'm obtaining data from various sensors and transmitting it to a webpage hosted on the same board. After doing some research online, I learned that it's considered "better" to ...

Modify the dropdown menu title dynamically based on the selection made in Angular

My Angular web-application has a dropdown menu that looks like this: <div class="btn-group" dropdown> <button dropdownToggle type="button" class="btn btn-primary dropdown-toggle">NAMEOFDROPDOWN <span class="caret"></span>&l ...

Stop users from being able to input line breaks by pasting

I am currently facing a challenge with my code. Within the code, I have included a textarea where users can input the title of an article, and I want this title to be restricted to only one line. To achieve this, I created a script that prevents users from ...

Implementing an OnChange Event for a Multi-Select Feature in a Vue.js Application

Here is the HTML code for my multi-select input: <select id="invitees_list1" class="form-select" multiple name="multi"> @foreach ($seatedTable->invitees as $invitee) <option> {{ $invitee ...

Using Sweetalert2 to send data via AJAX POST request

Recently, I've been incorporating SweetAlert2 into my project and I want to create an "Add Note" feature. The process involves the user clicking a button, being directed to a page, and then the following script is executed: <script>swal({ ...

Error: The function callback.apply is not a valid function (Node.js and Mongodb)

Encountered an error when adding the line "{ upsert: true }": Error message: TypeError: callback.apply is not a function // Accessing routes that end in /users/competitorAnalysisTextData // ---------------------------------------------------- router . ...

Is npm bundled with node-gyp?

I am currently experiencing an issue where running npm install locally does not produce much output when using npm v6.14.9. However, when I deploy to the server, it generates some incomprehensible messages like: gyp info spawn args ['some properties a ...

How to effectively share an object array between controllers when utilizing modal windows in AngularJS

I'm currently working with an array of objects that I need to share between two controllers, one of which involves a modal window. Check out the JavaScript code below: angular.module('MyApp', ['ngMaterial', 'ngMessages' ...

What steps can be taken to ensure a function operates even when the mouse is stationary?

$(document).ready(function() { var score = 0; $("body").mousemove(function() { score++; $("#result").val(score); console.log(score); }); }); As I move my mouse, the score keeps increasing. But, I'm wonde ...