0
function printAll(strs: string | string[] | null) {
  if (strs && typeof strs === "object") {
    for (const s of strs) {
      console.log(s);
    }
  } else if (typeof strs === "string") {
    console.log(strs);
  }
}

https://www.typescriptlang.org/docs/handbook/2/narrowing.html

Here I have broken the big if statement into two parts as follows. The ... show the part that I am not referring to.

I can understand that here if ( ... typeof strs === "object") { we are comparing the type of the variable because it can contain other types too.

I do not understand this: if (strs === "object" ... ) {. What is the purpose of this statement?

5
  • 3
    please re-read your question, seems like you have a typo and it's not clear what you are asking Commented Apr 26, 2021 at 9:24
  • 6
    Where is if (strs === "object") {? Commented Apr 26, 2021 at 9:25
  • if (strs && typeof strs === "object") is saying "if strs is truthy and strs's type descriptor is "object"". the double amerpsand (&&) delimits the two conditions. Commented Apr 26, 2021 at 9:28
  • Like mentioned, your question is slightly muddled. But I'm assuming your asking why the if (typeof strs === 'string'), and not just use } else {,.. It's because strs could still be null. Commented Apr 26, 2021 at 9:36
  • @FelixKling I got your point now. Thanks for your patience. Commented Apr 26, 2021 at 13:14

3 Answers 3

2
if (strs && typeof strs === "object")

is not the same as

if (strs === "object" && typeof strs === "object")

which is what you seem to be thinking. It's equivalent to

if (Boolean(str) && (typeof strs === "object"))

Why is it necessary to check whether str is a "truthy" value? Because typeof returns "object" for two data types: Object values and Null values (i.e. null):

console.log(typeof {});
console.log(typeof null);

So if you only did if (typeof strs === "object"), strs could still be null and therefore the for loop would fail (or in this case TypeScript would complain).

The code could have been written as

if (strs !== null && typeof strs === "object")

to be more explicit.

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

2 Comments

strs !== null doesn't eliminate undefined
@CallumMorrisson: True, but that should already be a compile time error because the type of strs is string | string[] | null.
1

I've re-ordered the code a little and added some comments. Hope it answers you question:

function printAll(strs: string | string[] | null) {
  // handle the null case
  if (strs == null) {
    return
  }

  // handle the string[] case
  if (typeof strs === "object") {
    for (const s of strs) {
      console.log(s);
    }
    return
  }

  // if we reached this point strs is a string, we could check here if (type strs === 'string') but it's redundant
  console.log(strs);
}

3 Comments

It's not equivalent to the original code though. The case where str === "" is different.
I would also recommend Array.isArray instead of typeof x === "object" for checking if something is an array
I wanted to stay close to the OP's question
1
function printAll(strs: string | string[] | null) {
  if (strs && typeof strs === "object") {
    for (const s of strs) {
       console.log(s);
    }
  } else if (typeof strs === "string") {
    console.log(strs);
  } else {
    // do nothing
  }
}

In the printAll function, you can pass inputs as string, string[], or null

let fruits: string[] = ['Apple', 'Orange', 'Banana'];
printAll(fruits);
let fruit: string = 'peach';
printAll(fruit);

So in case of string array type of strs is object and in the other case its string as expected.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.