8
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?

0

1 Answer 1

9

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.

Sign up to request clarification or add additional context in comments.

5 Comments

The return type from the map is identified as { id: string; name: string; ceo: string; }[] -- that much is fine. I think the question is why does tsc not complain when you try to return that value as a input[] but it fails when trying to directly return [{ id: '1', name: '2', ceo: 'Eric' }]?
@p.s.w.g Because TS will only complain about excess property checks when an object literal is directly assigned to something that is expected to be of a specific type. In this case the map call gets typed independently , and the return type is types as an array of type { id: string , name: string , ceo: string }[]. Then this is assigned to an array of type input[] which is allowed and no excess property checks are performed
@TitianCernicova-Dragomir Good explanation. I think that for the answer to be considered complete, it should include those details.
@p.s.w.g I would agree, apokryfos is free to include any part of that comment if he wants, his solution is the same code I would have posted so I'm not going to add an answer myself
Thank you for the comments. I've updated my answer to hopefully cover the details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.