基于TypeScript中字符串内容的重载函数

问题描述

我有一个接受input字符串参数的函数。如果input"!"字符开头,则该函数应返回boolean类型。如果input"?"字符开头,则该函数应返回string[]类型。

问题是,是否有可能在TypeScript定义文件中记录此类行为的重载?

解决方法

这是不可能的。

打字稿中的字符串可以是常量文字字符串,例如:

const a = "A"

或者它可能是string类型,这意味着它可能具有任何内容,例如:

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

无法定义与任何类型的模式匹配的字符串类型。


我不知道您要做什么,但是这里可能有更好的方法来设计API。


如果您确实了解所有可能性,则可以将它们视为常量字符串。

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


更新Typescript 4.1:

Typescript 4.1(仅在2020年9月18日以beta版本发布)包括对Template Literal Types的支持。这使您可以强类型化字符串文字的内容。现在,您可以取出一部分字符串文字,并单独使用它们。

有了此功能,您的问题可以像这样解决:

// 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