2

Let's say I have code along the lines of this:

function defaultIt(s: MaybeString): string {
  if (typeof s.content === "string") {
    return s.content;
  }

  return "";
}

class MaybeString {
  content: string|void;
}

Correct me if I'm wrong, but I believe this is about as type-safe as you can get; any possible input that fits MaybeString will result in a string. However, TypeScript gives me an error: Type 'string | void' is not assignable to type 'string'.

How can I get TypeScript to recognize that I've removed ambiguity by checking the type?

Thanks!

River Tam
  • 3,096
  • 4
  • 31
  • 51
  • Admittedly, I've only been using Typescript for a few months, but does it makes sense to type `content` as `string|void`? This is a "union type" correct? So what you're saying by doing that is the `content` property ONLY has the properties that are common between `string` and `void` (and since `void` has no properties at all, `string|void` is basically the same thing as `void`). Are you trying to say the `content` property is optional and may not have a value? – Sunil D. Sep 07 '15 at 19:39
  • I suppose I misunderstood. I thought it was kind of like a "Maybe" sort of thing. Is there a way to say it can be *either* a string or void? – River Tam Sep 07 '15 at 19:41
  • I deleted my answer b/c it was about optional properties on interfaces. But you basically don't need to do anything special (regarding typescript declarations) if the class property is optional. This was the conclusion I came to after you pointed out my mistake, and it's backed up by [this answer](http://stackoverflow.com/a/18916914/398606). – Sunil D. Sep 07 '15 at 19:56
  • I suppose my question is more general, but I was trying to simplify it. What if I want to make it either a string or a function, for example? – River Tam Sep 07 '15 at 19:58

1 Answers1

2

Currently you can use additional variable:

var temp:string|void = s.content;

if (typeof temp === "string") {
   return temp;
}

sample

Or cast to string:

if (typeof s.content === "string") {
   return <string>s.content;
}

sample

For classes you can use instanceOf function, see this article for details

Max Brodin
  • 3,903
  • 1
  • 14
  • 23
  • It's a little weird that you can do that, actually, considering `s.content` is already of type `string|void` – River Tam Sep 07 '15 at 20:42