Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to define a type under forEach in typescript?

I have an array of PersonTypes objects and would like to only use partial of key inside a forEach loop. what is more precise, correct coding in typescript to provide a type? I can do something like people.forEach((person: Pick<PersonTypes, 'name' | 'gender'> or people.forEach((person: PersonTypes) =>{ or people.forEach((person: any) =>{ what is right way to code in typescript

export type PersonTypes = {
  name: string;
  value: string;
  gender: boolean;
};
const people: PersonTypes[] = [
  {name: 'apl', value: 'apple', gender: true},
  {name: 'gal', value: 'google', gender: false},
]
people.forEach((person: Pick<PersonTypes, 'name' | 'gender'>) =>{
//people.forEach((person: PersonTypes) =>{
//people.forEach((person: any) =>{
  console.log(person.name);
  console.log(person.gender);
} )
like image 906
jacobcan118 Avatar asked Apr 14 '20 14:04

jacobcan118


People also ask

How do you define a type in TypeScript?

The any type allows us to assign literally “any” particular value to that variable, simulating what we know as plain JavaScript - where types can dynamically be assigned from different types, such as a String value becoming a Number.

Can you use forEach in TypeScript?

forEach() is an inbuilt TypeScript function which is used to calls a function for each element in the array.

How do you define an array of objects in TypeScript?

To declare an array of objects in TypeScript, set the type of the variable to {}[] , e.g. const arr: { name: string; age: number }[] = [] . Once the type is set, the array can only contain objects that conform to the specified type, otherwise the type checker throws an error. Copied!


2 Answers

You should just stick to:

people.forEach((person: PersonTypes) =>{


});

This is because each object within the people array is of type PersonTypes, and there is no actual need to extract properties away from the type.

In fact, there is no need to explicitly type person as PersonTypes, as people is of PersonTypes[]. TypeScript will automatically infer that each object within the array is PersonTypes, so this would be sufficient:

people.forEach((person) =>{


});  

Alternatively, you may choose to destructure the parameter, which will make your function more concise and clean.

people.forEach(({ name, gender }) =>{  
  console.log(name);
  console.log(gender);
});
like image 128
wentjun Avatar answered Jan 01 '23 10:01

wentjun


Based on the additional code you have provided, the customZip function is returning type of any, which of course causes issues later because the array will have a type of any instead of an inferred PersonType[]:

export function customZip(...arrays: Array<any>){
  return arrays
}

To fix this, it is as simple as using the concept of generics in TypeScript, which allows the compiler to infer the type of the array by itself:

export function customZip<T>(...arrays: Array<T>){
  return arrays
}

See proof-of-concept example.

You can choose to provide a type, or simply let TypeScript infer by itself. It doesn't really matter at this point: both will compile correctly:

// You let TypeScript do the inferring by itself
const people = [
  ...customZip([{name: 'apl', value: 'apple', gender: true},
  {name: 'gal', value: 'google', gender: false},])
];

...or...

// Your manually inform TypeScript what the type of an array member returned from customZip looks like
const people = [
  ...customZip<PersonTypes[]>([{name: 'apl', value: 'apple', gender: true},
  {name: 'gal', value: 'google', gender: false},])
];
like image 34
Terry Avatar answered Jan 01 '23 08:01

Terry