0

Say I have a function which accepts an input string parameter. If input begins with a "!" character, the function should return a boolean type. If input begins with a "?" character, the function should return a string[] type.

The question is, is it possible to document overloads for this kind of behavior in a TypeScript definition file?

1
  • No; that's a matter of value, not of type. If you know the full set of values you could use string literal types, but I don't think you can do it for a prefix. Commented Aug 31, 2020 at 21:45

1 Answer 1

1

This is not possible.

A string in typescript can either be a constant literal string, for example:

const a = "A"

Or it may be of type string which means it may have any content, for example:

const str = prompt("What is your name?")`

There is no way to define a string type that matches any sort of pattern.


I don't know what you are trying to do, but there's probably a better way to design your API here.


If you do know all possibilities, you can treat them like constant strings.

type Bang = "!A" | "!B" | "!C"
type Question = "?A" | "?B" | "?C"

function doStuff(str: Bang): boolean
function doStuff(str: Question): string[]

function doStuff(str: Bang | Question): boolean | string[] {
  if (str.startsWith("!")) {
    return true
  } else {
    return ['strings', 'here']
  }
}

doStuff('!A') // boolean
doStuff('?A') // string[]

Playground


Update for Typescript 4.1:

Typescript 4.1 (just released in beta on Sept 18, 2020) includes support for Template Literal Types. This lets you have the contents of string literals be strongly typed. You can now pull parts of string literals out and use them on their own.

With this feature, your problem could be solved like so:

// Typescript 4.1
function doStuff<
  Prefix extends '!',
  Suffix extends string
>(str: `${Prefix}${Suffix}`): boolean

function doStuff<
  Prefix extends '?',
  Suffix extends string
>(str: `${Prefix}${Suffix}`): string[]

function doStuff<
  Prefix extends '!' | '?',
  Suffix extends string
>(str: `${Prefix}${Suffix}`): boolean | string[] {
  if (str.startsWith("!")) {
    return true
  } else {
    return ['strings', 'here']
  }
}

doStuff('!A') // boolean
doStuff('?A') // string[]
doStuff('bad format') // type error

4.1 Playground

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

4 Comments

I've added an example for using constant strings if you know all possible values the strings could be ahead of time. Maybe that will help save some of those hours :)
I don't what your dataset looks like but, this would be easy if you could type that data structure like { id: string, type: 'entity' | 'item' } instead of relying on a specific format of identifier. But that probably doesn't help you :)
I was able to update my implementation and no longer need the prefix thing, but I really appreciate the fact that you just gave a straight answer, you're a rare breed on this website. Keep it up man.
@HarrisonSmith Typescript 4.1 was just released in beta and it has a feature that gives you what you initially asked for. Just in case this is still a problem for you, see my update.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.