Skip to content
FLAVIO COPES
flaviocopes.com

TypeScript type for a string or array of strings

By

Learn how to declare a TypeScript type that can be either a string or an array of strings using a union, written as string or string[].

~~~

Simple one, but I forgot the exact syntax and had to search for it, so let me write it:

export interface Props {
  tag: string | string[]
}

tag can be a string, or an array of strings.

The | creates a union type: the property accepts either form. The same works with a type alias:

type Props = {
  tag: string | string[]
}

I hit this writing an Astro component that takes either one tag or a list of tags. Both call sites should work, and with the union they do:

const one: Props = { tag: 'typescript' }
const many: Props = { tag: ['typescript', 'javascript'] }

Reading the value back

The union is convenient for callers, but it puts a small burden on the reading side. When you read tag, TypeScript only allows operations that exist on both types. Call an array method directly and it complains:

Property 'map' does not exist on type 'string | string[]'.
  Property 'map' does not exist on type 'string'.

The fix is to narrow with Array.isArray(), which is the runtime check TypeScript understands for arrays:

function normalizeTags(tag: string | string[]) {
  return Array.isArray(tag) ? tag : [tag]
}

When the check is true, tag is a string[] and is returned as-is. When it is false, tag must be a string, so wrapping it in brackets produces an array. The return type is inferred as string[] without any annotation.

This is the pattern I recommend: accept two convenient input shapes at the boundary, then normalize them immediately. Call normalizeTags() once, and the rest of the component works with a plain string[] — no repeated Array.isArray() checks scattered through the code.

The same union works anywhere, not just in component props. A function parameter typed string | string[] gives callers the same flexibility, with the same one-line normalization inside.

Exercise: reject an array containing a number, then hover over the result of normalizeTags('typescript').

~~~

Related posts about typescript: