TypeScript requires that the `includes` function must have the same type parameter for both input and

When working with TypeScript, I've encountered an interesting dilemma regarding the use of the Array.Prototype.includes function. It seems that this function requires me to pass in the same type as in the original array, but isn't the purpose of using includes to determine if a key of arbitrary string type exists in an array with a known type?

Let's consider the following code snippet:

type CONFIG_MODEL = {
  URL: string;
  Protocol: string;
  Port: number;
  Encrypted: boolean;
}

const ALLOWED_KEYS: (keyof CONFIG_MODEL)[] = ['URL', 'Protocol'];

function setup(configs: { [key: string]: string }) {
  Object.keys(configs).forEach(configKey => {
    if (ALLOWED_KEYS.includes(configKey)) {
      // do something
    }
  })
}

Link to TypeScript Playground

It turns out that TypeScript throws an error when trying to use includes, with the message:

Argument of type 'string' is not assignable to parameter of type 'keyof CONFIG_MODEL'

Any insights or suggestions would be greatly appreciated!

Answer №1

To enhance efficiency, consider looping through only the allowed keys instead of all object keys Here is an example:

type CONFIG_MODEL = {
  URL: string;
  Protocol: string;
  Port: number;
  Encrypted: boolean;
}

type AllowedKeys = Array<keyof CONFIG_MODEL>;

const ALLOWED_KEYS: AllowedKeys = ['URL', 'Protocol'];

const hasProperty=<Obj,Prop extends string>(obj:Obj,prop:Prop):obj is Obj & Record<Prop,string>=>
  Object.prototype.hasOwnProperty.call(obj,prop);

function setup(configs: { [key: string]: string }) {  
  ALLOWED_KEYS.forEach(elem=>{
    if(hasProperty(configs, elem)){
      // process the config
      const result = configs[elem] // valid
    }
  })
}

Answer №2

The as string[] conversion right before the .includes method in the code snippet below effectively handles the issue:

//type defined externally in original code
type ClassicalElement = 'earth' | 'water' | 'wind' | 'fire'; 
const classicalElements = ['earth', 'water', 'wind', 'fire'] as ClassicalElement[];
const isClassicalElement = function(
    possibleElement: string
): possibleElement is ClassicalElement {
    return (classicalElements as string[]).includes(possibleElement);
}

You can test this code snippet on TypeScript Playground using the following links: with and without encountering any errors.

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

Uploading Files with Angular 2 using AJAX and Multipart Requests

I am currently working with Angular 2 and Spring MVC. At the moment, I have an Upload component that sends an AJAX request to the Spring backend and receives a response containing parsed data from a .csv file. export class UploadComponent { uploadFile: f ...

Similar to `util.inspect` in Node.js, Deno also has a function

Is there a utility function in Deno that can stringify an Object or primitive similar to Node.js util.inspect? For instance, if I have a JSON object in Node.js and want to display its contents: > m = {k1:'v1', k2:'v2'} { k1: ' ...

How can I retrieve the `checked` state of an input in Vue 3 using Typescript?

In my current project, I am using the latest version of Vue (Vue 3) and TypeScript 4.4. I am facing an issue where I need to retrieve the value of a checkbox without resorting to (event.target as any).checked. Are there any alternative methods in Vue tha ...

What is the best way to globally incorporate tether or any other feature in my Meteor 1.3 TypeScript project?

I've been working hard to get my ng2-prototype up and running in a meteor1.3 environment. Previously, I was using webpack to build the prototype and utilized a provide plugin to make jQuery and Tether available during module building: plugins: [ ne ...

How to set return types when converting an Array to a dynamic key Object in Typescript?

Can you guide me on defining the return type for this function? function mapArrayToObjByKeys(range: [string, string], keys: { start: string; end: string }) { return { [keys.start]: range[0], [keys.end]: range[1] } } For instance: mapArrayToObj ...

I am experiencing slow load times for my Angular 2 app when first-time users access it, and I am seeking assistance in optimizing its speed

Below, you'll find a snippet from my app.ts file. I'm currently working with angular2, firebase, and typescript. I'm curious if the sluggish performance is due to the abundance of routes and injected files? The application functions smoot ...

How can one effectively outline the structure of a document within firestore?

Currently, I am enclosing my calls to Firebase within a function so that I can specify the return type within the function. This allows me to define the type of data being retrieved from a document. However, TypeScript complains if you do not convert the F ...

Organize library files into a build directory using yarn workspaces and typescript

When setting up my project, I decided to create a yarn workspace along with typescript. Within this workspace, I have three folders each with their own package.json /api /client /lib The main goal is to facilitate code sharing between the lib folder and b ...

Is it feasible to have two interfaces in Typescript that reference each other?

I am facing an issue with two interfaces, UserProfile and Interest. Here is the code for both interfaces: export default interface UserProfile { userProfileId: string, rep: number, pfpUrl: string, bio: string, experience: "beginner" | " ...

Is it possible to lengthen a function in TypeScript?

I am part of a team responsible for maintaining a unique JavaScript library that generates spy functions. These spy functions are designed to allow users to monitor how a function is called, primarily used in the context of unit testing. Our library creat ...

Angular2: Unable to locate the 'environment' namespace

After configuring my tsconfig.json, I can now use short import paths in my code for brevity. This allows me to do things like import { FooService } from 'core' instead of the longer import { FooService } from '../../../core/services/foo/foo. ...

What steps should I take to resolve the issue of 'unable to locate the name 'OktaAuthService' error?

I am currently trying to incorporate authentication into an Angular application using Okta. I have carefully followed the step-by-step instructions provided in the documentation at this link: . However, I am encountering an error when attempting to start t ...

The error message "SyntaxError: Cannot use import statement outside a module" popped up while working with discord.js, typescript, heroku

// Necessary imports for running the discord bot smoothly import DiscordJS, { TextChannel, Intents, Message, Channel, NewsChannel, ThreadChannel, DiscordAPIError } from 'discord.js' type guildTextBasedChannel = TextChannel | NewsChannel | ThreadC ...

Tips for fixing the error message "unable to access property 'property-name' of null"

I need assistance with retrieving data from a firebase database and storing it in an array using typescript. Below is the code snippet I am working with: export class ViewUserPage { public list = []; public ref = firebase.database().ref(); public ...

Cucumber Wrangler

I am completely new to using protractor/cucumber and restler in Typescript. The code below is what I have so far for hitting an endpoint URL and getting the response: Given('Hit the {string}', async (string) => { browser.quit() var data: ...

Having Trouble Adding Details to a New Cart for a User in Angular and MongoDB - What's Going On?

After working on an E-Commerce site for a while, I hit a roadblock. Despite taking a break and coming back with determination, I can't seem to resolve the issue at hand. The application features registration, login, product search, and a popup window ...

transform an array encoded in base64 format into a JSON object

I am encountering an issue where the base64 array I'm trying to send to an API is coming up empty. Here's a breakdown of what I'm doing: Firstly, I have an array of files with images in my code: [0: File {name: '766_generated.jpg' ...

What could be the reason for the Angular dropdown values not appearing?

Encountering an issue with binding data to a dropdown element, as the dropdown displays NOTHING SELECTED. <select #classProductTypeCombobox name="classProductTypeCombobox" class="form-control col-md-3" [(ngModel)]="classifica ...

Attempting to display two separate d3 line graphs within a single Ionic2 page

I am facing an issue with including multiple similar graphs on a single page within an Ionic2 application. I am utilizing the d3-ng2-service to wrap the d3 types for Angular2. The problem arises when attempting to place two graphs in separate div elements ...

Problems with updating HTML/Typescript in Visual Studio and Chrome are causing frustration

While working on my company's application locally and making HTML/TS changes, I am facing an issue. Whenever I save/hot reload and refresh the browser, no changes seem to take effect. I've tried stopping debugging, building/rebuilding, and runni ...