Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does typescript not check types on the result of an Array.map?

interface Company {
  id: string;
  name: string;
}

type input = Company;

// This fails as the types don't match
const ACME: input = { id: '123', name: 'ACME', ceo: 'Eric' };

function mapIds(ids: string[]): input[] {
  // This compiles, but it shouldn't, or is Array.map returning something different?
  return ids.map(id => ({ id: '1', name: '1', ceo: 'Eric' }));

  // This fails as types don't match
  return [{ id: '1', name: '2', ceo: 'Eric' }];
}


Given the above code, the typescript compiler will not allow the function to return values that don't belong in the type, however if the return is from an Array.map, it does. You can see this with the above snippet on the Typescript Playground: https://www.typescriptlang.org/play/

Could anyone explain what's up with that?

like image 538
bag-man Avatar asked Jan 30 '19 16:01

bag-man


People also ask

What does map return in TypeScript?

Return Value: This method returns the created array. Below examples illustrate the Array map() method in TypeScript.

Is array a data type in TypeScript?

In typescript, an array is a data type that can store multiple values of different data types sequentially. Similar to JavaScript, Typescript supports array declaration and there are multiple ways to do it. Declaring and Initializing Arrays: We can either use var or let for declaring an array.

How do you define a type map in TypeScript?

To define a Map object in TypeScript, use a generic to set the type of the Map's keys and values. All of the key-value pairs you add to the Map have to conform to the specified type, otherwise the type checker throws an error. Copied! We used a generic to declare a Map that has string keys and string or number values.


1 Answers

Your map function does not specify a return type so it can return anything. If you want a stricter check you need to be explicit:

interface Company {
  id: string;
  name: string;
}

type input = Company;

// This fails as the types don't match
const ACME: input = { id: '123', name: 'ACME', ceo: 'Eric' };

function mapIds(ids: string[]): input[] {
  return ids.map((id):Company => ({ id: '1', name: '1', ceo: 'Eric' }));

  // This fails as types don't match
  return [{ id: '1', name: '2', ceo: 'Eric' }];
}

The reason is that the .map function is a mapping operation intended to transform each element in the array to a new type. TypeScript does not know what that new type will be if you don't specify.

To expand on the comments below. TSC objects to line return [{ id: '1', name: '2', ceo: 'Eric' }]; because it expects a type of input[] which it is not. However ids.map(id => ({ id: '1', name: '1', ceo: 'Eric' })); by itself is fine (because .map can return any type) and that is then assigned to input[] which is allowed.

Thanks to @TitianCernicova-Dragomir and @p.s.w.g for their comments on this.

like image 194
apokryfos Avatar answered Sep 18 '22 14:09

apokryfos