The data type 'string | boolean' cannot be assigned to type 'never'. Only the data type 'string' is allowed to be assigned to type 'never'

interface popup {
    title: string;
    isActive: boolean;
}

type Option = "title" | "isActive";

const data: popup = retrieveData();

function retrieveData(): any {
    return {
        title: "Greetings"
    }
}

class Popup {
    title: string;
    isActive: boolean;
    constructor() {
        this.title = "";
        this.isActive = false;
        Object.keys(data).forEach((option: string) => {
            this[option as keyof popup] = data[option as keyof popup];
        })
    }
}

I encountered an issue at this[option as keyof popup]

Error details: Type 'string | boolean' is not compatible with type 'never'. Type 'string' cannot be assigned to type 'never'. https://i.sstatic.net/P2hZY.png

Answer №1

Object.keys always returns a string[], regardless of the input. It might be expected to return Array<keyof typeof obj>, but that is not the case. For more information, please refer to this list of issues on github.

In such cases, it is advisable to use a type assertion.

(Object.keys(obj) as Array<keyof typeof obj>)

However, the struggle does not end there. There is still an error present:

this[key] = obj[key]; // error

In general, TypeScript tends to discourage mutations. To delve deeper into this topic, you can check out my article and this answer.

The types of this[key] and obj[key] are both string | boolean.

Consider the following code snippet:

type Key = "name" | "check";

let _name: Key = 'name'
let _check: Key = 'check'
obj[_name] = obj[_check] // error

This code bears close resemblance to yours, except for the fact that your mutation occurs within an iterator while mine does not. There is no direct correlation between the iteration index and the type of key.

Take this example:

(Object.keys(obj) as Array<keyof typeof obj>)
  .forEach((key, index) => {
    if (index === 0) {
      const test = key // keyof modal and not "name"
    }
  })

This behavior is correct because even according to JavaScript specifications, there is no guarantee that the first key will be name. JS engine reserves the right to return keys in any order. While you may usually get the anticipated order in 99.99% of cases, it doesn't assure you of a specific sequence.

So, why does the error message mention never? TypeScript combines the expected keys in a union to ensure a common type. The intersection of string & boolean results in never, hence the error message.


To avoid using type assertions, one effective approach is to utilize reduce:

interface modal {
  name: string;
  check: boolean;
}

type Key = "name" | "check";

const obj: modal = fn();

function fn(): any {
  return {
    name: "hello"
  }
}

class Modal implements modal {
  name: string;
  check: boolean;
  constructor() {
    this.name = "";
    this.check = false;
    const result = (Object.keys(obj) as Array<keyof typeof obj>)
      .reduce((acc, key) => ({
        ...acc,
        [key]: obj[key]
      }), this)
    Object.assign(this, result)
  }
}

Playground It is recommended to either use implements modal or capitalize the modal interface.

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

What is the best way to retrieve an array within a list using React.JS and Typescript?

Imagine there is an array represented by the variable list: let list = [ { id: '1', ]; Now, when a certain function is executed, the expected outcome should transform the array into this format: result = [ { id: '6', }, ] ...

Getting a JSON value and saving it to a variable in Angular 4

Here is the JSON structure: { "Semester": [ { "queueName": "Science", "totalCount": 300, "unassignedCount": 10, "subjectDetails": [ { "subjectName": "Chemistry", "sectionOne": 100, "secti ...

Exploring the functionality of angular reactive forms in creating intricate JSON structures

After numerous attempts to resolve the issue on my own, I am reaching out to an Angular developer for assistance. My goal is to display a JSON object in the UI: Here is the JSON Object : items={"departure":"New York","arrival":"California","stations":[ ...

Angular implementation of a reactive form including a child component

Upon inspection, I noticed that my father form component is displaying the values of nickName and name, but not the value of age. It seems that {{myFormFather.status}} does not recognize the component child. It's almost as if my child component is inv ...

Implement a system in Angular Service that automatically generates user IDs for an array of user inputs

How can I automatically increment the user ID for each new user input and use that value for deletion or updating of specific entries? If a user adds their details as shown in the output picture link below, I want to display the output in a similar format ...

Issue: initial-es5 bundle size exceeds budget limit. The total size is 6.13 MB, which exceeds the 6.00 MB budget by 133.51 kB

I recently upgraded my Angular application to version 11. After running > ng build --prod I received the following output: √ Browser application bundle generation complete. √ ES5 bundle generation complete. Initial Chunk Files ...

Maintaining the generic types in mapped types in TypeScript

In my current project, I have a unique design where a class contains instance methods that act as handlers, each representing a specific operation. These handlers take a reference as input and assign the output to a second parameter. To simplify this proce ...

Leverage the power of React, Material-UI, and Typescript to inherit button props and incorporate a variety of unique

Looking to enhance the Material-UI button with additional variants like "square." How can I create a prop interface to merge/inherit props? Check out the following code snippet: import React from "react"; import { Button as MuiButton } from "@material-u ...

Type with optional conditional argument

In my current example, I am showcasing conditional arguments where the value of the second argument depends on the type of the first one. type Check<F, S> = S extends number ? string : number function Example<S>(arg: S) { return function ...

Modify marker location as data updates

I am currently utilizing the Google Maps API within a Vue.js project. In my project, I have a table of data that includes positions, and I am looking to update the marker positions dynamically without refreshing the entire card. Below is the code snippet ...

Tips for sequentially arranging and rearranging an array of numbers, even when duplicates are present

Encountered a perplexing issue that has me scratching my head in an attempt to visualize a solution. Currently, I am working with an array of objects that appears as follows: let approvers = [{order:1, dueDate: someDate},{order:2, dueDate: someDate}, ...

Issue with ngx-bootstrap custom typeahead feature malfunctioning

I'm facing an issue while trying to develop a customized typeahead feature that is supposed to search my API every time the user inputs something, but it's not functioning as expected. The autocomplete() function isn't even getting accessed. ...

Utilize the Lifecycle Interface within Angular 2 framework for enhanced application development

Can you explain the impact of this rule? "use-lifecycle-interface": true, ...

A guide to showcasing a series of strings in a react element

My aim is to present an array of strings on distinct lines within my React component by utilizing the following code: <div> {this.props.notifications.join('\n')} </div> Nonetheless, it appears that this a ...

Enhance your TypeScript skills by leveraging types on the call() method in redux-saga

Is there a way to specify the types of a function using call()? Consider this function: export function apiFetch<T>(url: string): Promise<T> { return fetch(url).then(response => { if (!response.ok) throw new Error(r ...

Is there a way to send both a file and JSON data in a single HTTP request?

Once I developed a small application using NestJs where I implemented a BFF (Backend for Frontend) service. Within this service, I tried to execute a POST request to create a new user while also including the user's avatar in the same request. Here is ...

Guide on integrating a Web Worker included in an NPM module within a NextJS project

If you're experiencing issues, refer to the Github Repository here: https://github.com/kyledecot/next-worker-bug Within my NextJS application, there is an NPM package that I have bundled using webpack/ts-loader. This package includes a web Worker & W ...

Assignment of Angular Component Class Variable in One Function Results in Undefined Value in Another

I am currently facing an issue with a component that has a ViewChild() binding to a child component, which is used to execute a function in the child component. This function takes a true or false argument and is intended to assign the value to a class var ...

How can I save a TypeScript object to Firebase using serialization?

Having an issue: Within my angular application, I have implemented a lot of classes with inheritance. However, upon attempting to save these objects to Firebase, I encountered an error indicating that I am trying to persist custom objects which is not supp ...

Solving issues with event handling through addEventListener within a functional component in React

I am working on a React component that includes an input field and I want to implement a character autocompletion feature. The idea is that when a user types " or ', the same character should be automatically added again, with the cursor placed i ...