Typescript error code TS7053 occurs when an element is detected to have an implicit 'any' type due to an expression of a different type

I encountered an issue with the provided example.

I'm uncertain about how to resolve it.

Your assistance would be greatly appreciated.


type TestValue = {
  value: string;
};

type FirstTest = {
  type: 'text';
  text: TestValue[];
};

type SecondTest = {
  type: 'heading';
  heading: TestValue;
};

type Test = FirstTest | SecondTest;

const firstTest: Test = {
  type: 'text',
  text: [
    {
      value: 'Text!!',
    },
  ],
};
const secondTest: Test = {
  type: 'heading',
  heading: {
    value: 'heading!!',
  },
};

const foo = (data: Test) => {
  const { type } = data;

  const content = data[type]; //Encountering error TS7053: Element implicitly has an 'any' type because expression of type '"text" | "heading"' can't be used to index type 'Test'.   Property 'text' does not exist on type 'Test'.

  switch (type) {
    case 'heading':
      return content.value;
    case 'text':
      return content[0].value;
  }
};

Unfortunately, I am faced with the error

TS7053: Element implicitly has an 'any' type because expression of type '"text" | "heading"' can't be used to index type 'Test'.   Property 'text' does not exist on type 'Test

Executing the foo function results in a type validation issue.

Answer №1

If you want to make the most of the discriminated union type, ensure that you only try to access data[type] within the corresponding block where type was discriminated. For example, within your switch statement:

const foo = (data: Test) => {
  const { type } = data;
  let content: FirstTest['text'] | SecondTest['heading']

  type // "text" | "heading"
  data // FirstTest | SecondTest
  data[type] // invalid as neither "text" nor "heading" appear on both FirstTest and SecondTest

  switch (type) {
    case 'heading':
      type // "heading"
      data // SecondTest
      content = data[type] // valid as SecondTest['heading'] exists
      return content.value;
    case 'text':
      type // "text"
      data // FirstTest
      content = data[type] // valid as FirstTest['text'] exists
      return content[0].value;
  }
};

In order to simplify, you can skip creating the content variable completely:

const foo = (data: Test) => {
  const { type } = data;

  switch (type) {
    case 'heading':
      return data[type].value; // valid
    case 'text':
      return data[type][0].value; // valid
  }
};

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

Create a randomized item for experimentation in NodeJs using an interface

Looking for a NodeJs package that can generate fake data in all required fields of a complex object described by a set of typescript interfaces, including arrays and sub-interfaces. Any recommendations? ...

Typescript sometimes struggles to definitively determine whether a property is null or not

interface A { id?: string } interface B { id: string } function test(a: A, b: A) { if (!a.id && !b.id) { return } let c: B = { id: a.id || b.id } } Check out the code on playground An error arises stating that 'objectI ...

Ensure that the dynamically inserted <title> tag remains intact in Angular even when the page is re

Can the dynamic title tag be preserved when the page is refreshed? When I refresh the page, the title tag reverts back to the original one specified in the index.html temporarily before switching back to the dynamically added one. I want the title tag to ...

There are several InputBase elements nested within a FormControl

There seems to be an issue: Material-UI: It appears that there are multiple InputBase components within a FormControl, which is not supported. This could potentially lead to infinite rendering loops. Please only use one InputBase component. I understand ...

No matter what I attempt, Ng-options is still failing to work properly

This is my custom selection element: <select ng-options="country.country for country in countries" formControlName="country"></select></label> Below is the TypeScript component code associated with it: import { Component } from ' ...

Issue with TypeScript Declaration File in NPM module functionality

Recently, I've been working on developing a package for NPM. It's essentially a JSON wrapped database concept, and it has been quite an enjoyable project so far. However, I've been facing some challenges when trying to include declarations f ...

Prevent redundancy by caching svg icons to minimize repeated requests

I have a collection of info cards on my page, each featuring its own unique illustration along with a set of common icons (SVG) for options such as edit, delete, and more. While the illustrations vary from card to card, the icons remain consistent across a ...

Creating a Dynamic Clear Button for a Text Area in Angular

Working on my Angular application, I have implemented a form with a textarea element. My goal is to incorporate a clear button inside the textarea element that should: Appear only when the textarea is focused Disappear when the textarea is out of focus ( ...

remove a specific element from an array

Hey there! I'm attempting to remove only the keys from an array. Here's the initial array: {everyone: "everyone", random: "random", fast response time: "fast response time", less conversations: "less conversatio ...

I'm having trouble grasping the concept of 'globals' in TypeScript/NodeJS and distinguishing their differences. Can someone explain it to me?

As I review this code snippet: import { MongoMemoryServer } from "mongodb-memory-server"; import mongoose from "mongoose"; import request from "supertest"; import { app } from "../app"; declare global { function s ...

Improving DynamoDb Query Results with Type Hinting

In the following Typescript code, how can I specify which fields should be present in my Query Items Result? const request: DynamoDB.DocumentClient.QueryInput = { TableName: UnsubscriptionTokensRepository.TABLE_NAME, IndexName: 'TokenIndex&ap ...

Transitioning from Webpack to Vite: Resolving Path Alias and Ensuring Proper Imports

Recently, I decided to transition my project from Webpack to Vite with "vite": "^4.3.9",. However, upon running npm start, I encountered the following error: Error: The dependencies imported could not be resolved: In my React Typesc ...

Navigating within components using code is an essential skill when working with Vue Router

I am currently developing a Quasar application powered by Vue 3 with vue-router version 4 All my routes are properly configured and function well when navigating from a component template using <router-link to="/route">Go to route</rout ...

Learn how to access nested arrays within an array in React using TypeScript without having to manually specify the type of ID

interface UserInformation { id:number; question: string; updated_at: string; deleted_at: string; old_question_id: string; horizontal: number; type_id: number; solving_explanation:string; ...

Utilizing backbone-forms in Typescript: A beginner's guide

Currently in my project, I utilize backbone.js along with typescript. My goal is to incorporate backbone-forms for form creation, however I am unable to locate a typescript definition file (d.ts) for this specific backbone plugin. Despite my attempts to cr ...

What is the process for defining the root of a project in ESLint?

I've been working on a project using Next.js and Typescript. My imports look like this: import Component from "/components/Component/Component";, with the root directory being specified as /src. This setup works fine in Next.js, but ESLint k ...

Guide on navigating to a different page using a function with router link in Angular using TypeScript

Trying my hand at Angualar and Typescript for the first time. I am working on creating a login page where users can move to another page if their credentials are correct. To achieve this, I want to use a function that is triggered by clicking a button. How ...

Creating a conditional statement within an array.map loop in Next.js

User Interface after Processing After retrieving this dataset const array = [1,2,3,4,5,6,7,8] I need to determine if the index of the array is a multiple of 5. If the loop is on index 0, 5, 10 and so on, it should display this HTML <div class="s ...

Guide to creating a one-to-one object literal map with a different value type using a function return without explicitly defining the return type

At the moment, I have successfully managed to combine the keys and values of each object literal that is passed into a function. For example: interface StaticClass<T = any> { new (...args: any[]): T } type RecordOfStaticClasses = Record<string, ...

Observing the completion of a subscriber function

Is there a more streamlined way to determine if the subscriber has finished executing or return something and catch it up-stream? Consider the following code snippets: this._subscriptions.push(this._client .getCommandStream(this._command) // R ...