Josh Silveous
Josh Silveous

Reputation: 763

TypeScript: get type of array?

I'm making a TypeScript function (fairly new to TS) that takes a parameter which can either be a number, a string, an array of numbers, or an array of strings.

I need to be able to tell the difference between those 4 in my code.

Whenever I run typeof on an array, it returns 'object'. How could I differentiate between an array of strings or an array of numbers in my code?

I know I could use some for loops or array methods to check the type of each index in the array, but is there a cleaner way?

function numToLet(input: number | number[] | string | string[]) {

if (typeof input === 'number') {
    console.log(`Input ${input} is a number.`)
}

if (typeof input === 'string') {
    console.log(`Input ${input} is a string.`)
}

if (typeof input === 'object') {
    console.log(`Input ${input} is an object. I dunno which kind though ¯\_(ツ)_/¯`)
}

}

Upvotes: 0

Views: 1296

Answers (1)

Michael Jay
Michael Jay

Reputation: 593

There's the Array method Array.isArray(). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray. I use it prolifically. Too much, maybe.

In an old project I worked on that didn't have strict mode enabled, Array.isArray() was a great way to handle both null AND unexpected values.

const myActualArray = ['apple','banana'];
const myUnArray = "apples and bananas";
let oops;

console.log(Array.isArray(myActualArray)); // true
console.log(Array.isArray(myUnArray)); // false
console.log(Array.isArray(oops)); // false
console.log(Array.isArray(null)); // false

Have you had a look at TypeScript generics, by the way? I'm just beginning to ruminate on them myself, so I don't think I can speak to whether or not they provide a good TypeScript solution for you - Array.isArray() is of course just a JS solution. https://www.typescriptlang.org/docs/handbook/2/generics.html

Edit to add after your comment: It seems like you're placing total faith in your code to send one of your four input types. All you have to do is stitch together your idea of using typeof with Array.isArray.

function numToLet(input: number | number[] | string | string[]) {

  if (typeof input === 'number') {
      console.log(`Input ${input} is a number.`)
  }

  if (typeof input === 'string') {
      console.log(`Input ${input} is a string.`)
  }

  if (Array.isArray(input)) {
      // If you're certain that your array is definitely EITHER a (non-empty) array of ALL numbers OR of ALL strings, just check the first element's type.
      if (typeof input[0] === 'number') {
        console.log(`Input ${input} is a number.`)
      }

      if (typeof input[0] === 'string') {
        console.log(`Input ${input} is a string.`)
      }
  }
}

Upvotes: 1

Related Questions