Home > other >  How to find correct type for map elements?
How to find correct type for map elements?

Time:11-14

The below code outputs [ 5142, 5143 ], but I use any as type.

let a = [{ _id: 5142 }, { _id: 5143 }];

a = a.map((e: any) => {
  return e._id;
});

console.log(a);

Looking at the types I would think the correct type would be

a = a.map((e: { _id: number }) => {

but it fails.

I use VSCode. Can it tell me the correct type? Or is there a clever console.log(typeof) trick?

CodePudding user response:

Fundamentally, assign the result of map to something else, not to a, since if you assign back to a then a has to be defined as number[] | { _id: number; }[] (since it starts out being { _id: number; }[] and then you're trying to turn it into number[]).

If you assign it to something else, then you don't need to specify any types at all, TypeScript will infer them correctly:

const a = [{ _id: 5142 }, { _id: 5143 }];

const b = a.map((e) => {
    return e._id;
});

console.log(b);

Playground link

It's possible to reuse a, but it's not clear why you'd want to. Here's what that would look like, but I don't recommend it:

let a: number[] | { _id: number; }[] = [{ _id: 5142 }, { _id: 5143 }];

a = a.map((e) => {
    return e._id;
});

console.log(a);

Playground link

TypeScript's flow analysis lets it see that when calling map, a is a { _id: number; }[], so we don't need a type guard. If it weren't obvious from context, you would:

function example(a: number[] | { _id: number; }[]) {
    a = a.map((e) => {
        return typeof e === "object" ? e._id : e; // Note the type guard
    });

    return a;
}

console.log(example([{ _id: 5142 }, { _id: 5143 }]));

Playground link

  • Related