What is the best way to retrieve a value from an array of objects containing both objects and strings in TypeScript?

Consider this scenario with an array:

const testData = [
  { properties: { number: 1, name: 'haha' } , second: 'this type'},
  ['one', 'two', 'three'],
];

The goal is to access the value of 'second', which is 'this type', in this manner:


const wantToGet = testData[0].second;

However, TypeScript throws an error stating:


Property 'second' does not exist on type 'string[] | { properties: { number: number; name: string; }; second: string; }'.
Property 'second' does not exist on type 'string[]'

It's worth noting that testData[0] always represents an object, not an array. Why is that?

Answer №1

Typescript recognizes that testData is a list containing either an array of strings or an object with the shape

{properties: {number: number; name: string;}
. Because testData[0] can be one of these two possibilities, it must be narrowed down for safe usage.

Alternatively, you can do:

const testData = [
  { properties: { number: 1, name: 'haha' } , second: 'this type'},
  ['one', 'two', 'three'],
] as const;

Answer №2

testData is determined to be of type ({ ... } | string[])[], similar to how

const thing = [1, "2", 3, "4"];

is inferred as (number | string)[]. To specify it as a tuple, you can utilize a const assertion,

const testData = [
  { properties: { number: 1, name: 'haha' } , second: 'this type'},
  ['one', 'two', 'three'],
] as const;

However, this will make testData immutable (including the object and array inside). If mutability is needed, an explicit type annotation should be provided:

const testData: [{ properties: { ... } ... }, string[]] = [
  { properties: { number: 1, name: 'haha' } , second: 'this type'},
  ['one', 'two', 'three'],
];

Alternatively, a helper function can be used to infer it as a tuple:

function tuple<T extends readonly unknown[]>(args: [...T]) { return args }

const testData = tuple([
  { properties: { number: 1, name: 'haha' } , second: 'this type'},
  ['one', 'two', 'three'],
]);

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

Switching from dark mode to light mode when reloading or navigating to a new page

Hello everyone. I've successfully implemented a dark mode toggle on my website, but I'm facing an issue where the mode resets whenever I navigate to a new page or refresh the current page. Can anyone help me figure out how to prevent this from ...

Distinguishing between type assertion of a returned value and defining the return type of a function

What distinguishes between performing a type assertion on a function's return value and explicitly typing the return value in the function signature? Let's consider only simple functions with a single return statement. interface Foo { foo: numbe ...

The process of modifying all interface values in typescript

Suppose I have a function that accepts a dynamic object as a parameter. const fun = <IValues>(values: IValues) => // IValues = {a: '', b: ''} My intention is to use that object and create a clone with the same keys but differ ...

Encountering a ReferenceError while attempting to implement logic on a newly created page

I've been experimenting with building a website using the Fresh framework. My goal was to add a simple drop-down feature for a button within a navigation bar, but I'm struggling to figure out where to place the necessary code. I attempted creatin ...

Angular 2 validation issue not functioning as anticipated

Here is a validator function that I have: export const PasswordsEqualValidator = (): ValidatorFn => { return (group: FormGroup): Observable<{[key: string]: boolean}> => { const passwordCtrl: FormControl = <FormControl>group.contr ...

Is it possible to create an observable with RXJS that emits only when the number of items currently emitted by the source observables matches?

I am dealing with two observables, obs1 and obs2, that continuously emit items without completing. I anticipate that both of them will emit the same number of items over time, but I cannot predict which one will emit first. I am in need of an observable th ...

Is it possible to determine the function type of a pointer to a member function?

If you possess a pointer to a member function in this manner: struct Foo { void func() {} }; void(Foo::*funcPtr)() = &Foo::func; Is there a technique to extract the function type without the Foo:: part? For example, void(Foo::*)() -> void(*)() ...

navigating through different pages on a react-native application

While building my app in react-native, I encountered some issues with setting up the navigation. I referred to the react-native documentation for guidance, specifically this navigation guide. The guide mentioned passing an object named "navigation" to your ...

Instructions for including a class are ineffective

I am trying to dynamically add a class to a div based on two conditions. To achieve this, I have created a custom directive as shown below: import { Directive, HostBinding, Input } from '@angular/core'; @Directive({ selector: '[confirmdia ...

Creating mock objects with Jest

I am currently delving into the world of jest testing. Here is a snippet from an implementation class I'm working with: import { ExternalObject } from 'external-library'; export class MyClass { public createInstance(settings : ISettings) ...

Tips for monitoring the loading of data in TypeScript with observers?

One of the methods in my class is responsible for fetching information from the server: public getClassesAndSubjects(school: number, whenDate: string) { this.classService.GetClassesAndSubjects(school, whenDate).subscribe(data => { if (!data.h ...

What is the correct way to include a JSON file in TypeScript?

Currently, I'm attempting to reference a JSON path and save it as a constant. My initial approach involved creating a reference with a string and then sending it back as a response using res.send, which successfully returned the string. However, I am ...

A guide on logging errors triggered within reducers

I'm facing a challenge in Redux where I am unable to get error messages logged to the console. My stack includes React, Redux Toolkit, and TypeScript. Here is a snippet of one of the reducers I've implemented: // Reducer const removeResourceRedu ...

In React and TypeScript, when I pass a state as a prop, the data fails to render

Here is the useState function for managing the Data Interestingly, removing this state from the code doesn't affect rendering at all. const [cart, setCart] = useState([] as Product[]); This piece of code handles Mapping and Rendering the Data <Sin ...

MUI Autocomplete refuses to accept a value

In my Autocomplete feature, I have a list of all users available. When a user clicks on a button from another site, they are redirected to this site and the user's ID is fetched. I want the user with the corresponding ID to be automatically selected, ...

Having trouble connecting 'chartData' to a 'div' in Angular 2 because it is not recognized as a valid property?

While working on my Angular project, I encountered the following error that I have been unable to resolve: EXCEPTION: Uncaught (in promise): Error: Template parse errors: Can't bind to 'chartData' since it isn't a known property of ...

What are the benefits of pairing Observables with async/await for asynchronous operations?

Utilizing Angular 2 common HTTP that returns an Observable presents a challenge with nested Observable calls causing code complexity: this.serviceA.get().subscribe((res1: any) => { this.serviceB.get(res1).subscribe((res2: any) => { this.se ...

Declaring Objects and Relationships in Angular Models

Wondering if it's possible to declare an object inside my model. First attempt: export class Employee{ emp_id: number; emp_fname: string; emp_lname: string; emp_birth: string; emp_status: string; emp_photo: string; emp_dep ...

Guide on linking enum values with types in TypeScript

My enum type is structured as follows: export enum API_TYPE { INDEX = "index_api", CREATE = "create_api", SHOW = "show_api", UPDATE = "update_api", DELETE = "destroy_api" }; Presently, I have a f ...

What is the correct way to assign multiple types to a single entity in TypeScript?

(code at the end) While attempting to write section.full.link, I encountered the following error: Property 'link' does not exist on type 'SectionSingle | SectionTitle | SectionHeaderMedia'. Property 'link' does not exist on ...