TypeScript: how to type fuse union type

A function compose

can take an object or an array of objects as an argument. In compose

type protection distinguishes between object and array. A function mapper

can only handle objects with type guards, only objects are bound to it.

interface Link {
   something: string;
}

function compose(link: Link|Link[]) {
  if (link instanceof Array) {
    R.map(function(l) {
      return mapper(l);
    }, link);
  } else {
      return mapper(link);
  }
}

function mapper(link: Link) {
  return link;
}

      

Compiling this example results in an error:

error TS2345: argument of type 'Ref | Link [] 'is not assigned to parameter of type "Link"

This error is understandable because mapper takes the union type as an argument, but expects only one object. This is not what I expected when I used the type guard. Any thoughts on this?

+3


source to share


1 answer


It seems that TypeScript 1.4.0.0 doesn't infer that it link

should have a type link

if it doesn't have a type Array

. A small change should address the following:

function compose(link: Link|Link[]) {
  if (link instanceof Array) {
    R.map(function(l) {
      return mapper(l);
    }, link);
  } else if (link instanceof Link) {
      return mapper(link);
  }
}

      



Alternatively, you can type assert:

return mapper(<Link> link);

      

+4


source







All Articles