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

Encountering a Next.js event type issue within an arrow function

After creating my handleChange() function to handle events from my input, I encountered an error that I'm unsure how to resolve. Shown below is a screenshot of the issue: I am currently working with Next.js. In React, this type of error has not been ...

Deeply nested .map function to update state value

The current state value const [settings, setSettings] = useContext(SettingsContext) Utilizing the .map method on the settings state {settings[categoryIndex]?.config?.map((item: ConfigItem, index: number) => ...

``Are you experiencing trouble with form fields not being marked as dirty when submitting? This issue can be solved with React-H

Hey there, team! Our usual practice is to validate the input when a user touches it and display an error message. However, when the user clicks submit, all fields should be marked as dirty and any error messages should be visible. Unfortunately, this isn&a ...

Encountering 'null' error in template with Angular 4.1.0 and strictNullChecks mode

After updating Angular to version 4.1.0 and activating "strictNullChecks" in my project, I am encountering numerous errors in the templates (.html) that look like this: An object may be 'null' All these errors are pointing to .html templat ...

Angular 6: Harnessing the Power of RouterLinks

Can you navigate to a different section of another page using the defined ID without having to reload the entire page? ...

The search for d.ts declaration files in the project by 'typeRoots' fails

// Within tsconfig.json under "compilerOptions" "typeRoots": ["./@types", "./node_modules/@types"], // Define custom types for Express Request in {projectRoot}/@types/express/index.d.ts declare global { namespace Express { interface Request { ...

Issue TS2769: No matching overload found for this call. The type 'string | null' cannot be assigned to type 'string | string[]'

export class AuthService { constructor(private http: HttpClient, private webService: WebRequestService, private router: Router) { } login(email: string, password: string) { return this.webService.login(email, password).pipe( shareReplay(), ...

Dismiss the necessity of imports in Angular

I am facing an issue with using a library in Angular, specifically the cubing npm package. This library is designed to run in both the browser and node environments, with specific code for each. I want it to run in the browser, but when compiling with Angu ...

Using TypeOrm QueryBuilder to establish multiple relations with a single table

Thank you for taking the time to read and offer your assistance! I am facing a specific issue with my "Offer" entity where it has multiple relations to "User". The code snippet below illustrates these relationships: @ManyToOne(() => User, (user) => ...

Step-by-step guide on implementing Form.create in TypeScript and Ant Design with function components

Having trouble compiling my form created using Form.create(). The error message I'm getting is: Argument of type 'FunctionComponent<MyProps>' is not assignable to parameter of type 'ComponentType<{}>'. Type 'Fu ...

The Java value is not returned by the Observable<boolean> stream

I'm currently working on making a request to the backend for a boolean value using observables, but I'm struggling to figure out the best approach between .map and .subscribe. return this.http.put({url}, credentials, this.requestOptions) .ca ...

Top method for managing dates in TypeScript interfaces received from the server

After encountering the issue detailed in Dates in a Typescript interface are actually strings when inspected I faced a challenge while defining a TypeScript interface for a response from a server API, particularly with a Date parameter. The data arrived a ...

What specific element is being targeted when a directive injects a ViewContainerRef?

What specific element is associated with a ViewContainerRef when injected into a directive? Take this scenario, where we have the following template: template `<div><span vcdirective></span></div>` Now, if the constructor for the ...

Is there a way to view the type signature of the resulting intersection type (type C = A & B) in IDE hints, rather than just seeing the components?

When analyzing types defined by intersection in Typescript, I notice that the hint remains identical to the original definition: https://i.stack.imgur.com/mjvI8.png However, what I actually want is to visualize the resulting shape, similar to this: http ...

Strategies for modifying the title attribute within an <a> tag upon Angular click event

I am attempting to dynamically change the title attribute within an anchor tag upon clicking it. The goal is for the title attribute to toggle between two states each time it is clicked. Currently, I am able to change the title attribute successfully upon ...

Receiving the [object HTMLInputElement] on the screen rather than a numerical value

I have an input box where a user can enter a number. When they click a button, I want that number to be displayed on the page. However, instead of seeing the number, I am getting the output as [object HTMLInputElement]. Below is my TypeScript code: let qu ...

Is there a way to tally up the overall count of digits in a number using TypeScript?

Creating a number variable named temp in TypeScript: temp: number = 0.123; Is there a way to determine the total count of digits in a number (in this case, it's 3)? ...

Beware: The use of anonymous arrow functions in Next.js can disrupt Fast Refresh and lead to the loss of local component state

I am currently encountering a warning that is indicating an anonymous object in a configuration file, and even specifying a name for it does not resolve the warning. Below you will find the detailed warning message along with examples. Warning: Anonymous ...

Using Typescript to import Eslint with the `import/named` method

My project utilizes Eslint with the following configurations: parser: @typescript-eslint/parser 1.4.2 plugin: @typescript-eslint/eslint-plugin 1.4.2 resolver: eslint-import-resolver-typescript 1.1.1 rule extends: airbnb-base and plugin:@typescript-eslint ...

Using "array_agg" in a "having clause" with Sequelize

I am facing a particular scenario with my database setup. I have three tables named computers, flags, and computerFlags that establish relationships between them. The structure of the computerFlags table is as follows: computerName | flagId computer1 | ...