Home > Software design >  How to get a value of object in an array of object and string in TS?
How to get a value of object in an array of object and string in TS?

Time:11-04

Let's say I have this array

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

I want to get the value of 'second' which is 'this type' like this:


const wantToGet = testData[0].second;

But the typescript generates an error saying


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

testData[0] is always an object, not an array. Why is that?

CodePudding user response:

What typescript knows is that testData is a list of either an array of strings or an object of shape {properties: {number: number; name: string;}. Because testData[0] can be either of the two, you need to narrow it down to use safely.

Or you can

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

CodePudding user response:

testData is inferred as ({ ... } | string[])[], just like how

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

is inferred as (number | string)[]. If you want it to be inferred as a tuple, you can use a const assertion,

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

but this makes testData immutable (even the object and array inside are immutable). If you want to be able to mutate it, you should give it an explicit type annotation:

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

Or you can use a helper function 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

  • Related