如何在Typescript中定义正则表达式匹配的字符串类型?

Our*_*ors 10 regex types typing typescript

是否可以定义一个包含字符串格式信息的接口?请看以下示例:

interface timeMarkers{
    markerTime: string[]        
};
Run Code Online (Sandbox Code Playgroud)

一个例子是:

{
   markerTime: ["0:00","1:30", "1:48"]                   
}
Run Code Online (Sandbox Code Playgroud)

我的问题:有没有办法定义类型markerTime,以便字符串值必须始终匹配此正则表达式,而不是简单地声明它string[]并从那里开始?

var reg = /[0-9]?[0-9]:[0-9][0-9]/;

Pat*_*Dan 24

type D1 = 0|1;
type D3 = D1|2|3;
type D5 = D3|4|5;
type D9 = D5|6|7|8|9;

type Hours = `${D9}` | `${D1}${D9}` | `2${D3}`;
type Minutes = `${D5}${D9}`;
type Time = `${Hours}:${Minutes}`;
Run Code Online (Sandbox Code Playgroud)

紧凑的解决方案聚合了来自@bela53@yoel halb的想法。

此解决方案有 2039 个 Time 类型的枚举成员。

TS游乐场


Tit*_*mir 16

没有办法定义这样的类型.有一项关于GitHub 的建议支持这一点,但它目前似乎不是一个优先事项.投票,也许团队可能会在未来的版本中包含它.

  • 让 x:MarkerTime = "99999:999999"; 也将有效,因为 ${number} 允许任何数字,而不仅仅是一位数字 (4认同)
  • 另外 `"93.242:942.23"` 也与此匹配。 (3认同)
  • 您可以进一步避免匹配 `"93.242:942.23"` : ```ts type SingleNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;类型 MarkerTime =`${SingleNumber| ''}${SingleNumber}:${SingleNumber}${SingleNumber}`; `` https://www.typescriptlang.org/play?#code/C4TwDgpgBAyglgOwOYBsIDkCuBbARhAJygF4oAGKAHygEYqoAmegZnoBZ6BWegNnoHZ6ADnoBOAFDjQkKAFkAhgQDWhACpxs0YgAMAJAG94yNFjyFqAcgsBfA0dQYc+AtYBcdxA9PP bhzyadCa21JNGAoeVc5RRUCdU0SKAAiMgBaMjIkqAB6bKhCAgB7AnEwqFwohWU1DS1kjNcMrNyoQqVSiHCAY0qYmoTSFNFGzJy8tskgA (3认同)

bel*_*a53 16

在 regex 类型可用于该语言之前,您现在可以在 TS 4.1 中使用模板文字类型

让我参考问题示例并说明,如何对string名为Time. 为简化起见,这里需要Time格式hh:mm(例如"23:59")的字符串。

第 1 步:定义HHMM类型

将以下代码粘贴到您的浏览器 Web 控制台中:
Array.from({length:24},(v,i)=> i).reduce((acc,cur)=> `${acc}${cur === 0 ? "" : "|"}'${String(cur).padStart(2, 0)}'`, "type HH = ")
Array.from({length:60},(v,i)=> i).reduce((acc,cur)=> `${acc}${cur === 0 ? "" : "|"}'${String(cur).padStart(2, 0)}'`, "type MM = ")
Run Code Online (Sandbox Code Playgroud) 生成的结果,我们可以将其用作 TS 中的类型:
type HH = '00'|'01'|'02'|'03'|'04'|'05'|'06'|'07'|...|'22'|'23'
type MM = '00'|'01'|'02'|'03'|'04'|'05'|'06'|'07'|...|'58'|'59'
Run Code Online (Sandbox Code Playgroud)

第 2 步:声明 Time

type Time = `${HH}:${MM}`
Run Code Online (Sandbox Code Playgroud)

就那么简单。

第 3 步:一些测试

const validTimes: Time[] = ["00:00","01:30", "23:59", "16:30"]
const invalidTimes: Time[] = ["30:00", "23:60", "0:61"] // all emit error
Run Code Online (Sandbox Code Playgroud)

这是一个实时代码示例,可以使用Time.

  • 对于看到这个答案的任何人来说,第一部分不是代码的一部分,而是应该提前完成以将所有组合作为字符串,然后可以将其用作常量字符串,这当然只是一个解决方案,如果您准备好的话您的代码中有数千个选项... (2认同)

yoe*_*alb 6

基于@bela53 的答案但更简单,我们可以做一个非常简单的解决方案,类似于@Titian 但没有缺点:

type HourPrefix = '0'|'1'|'2';
type MinutePrefix = HourPrefix | '3'|'4'|'5';
type Digit = MinutePrefix |'6'|'7'|'8'|'9';

type Time = `${HourPrefix | ''}${Digit}:${MinutePrefix}${Digit}`

const validTimes: Time[] = ["00:00","01:30", "23:59", "16:30"]
const invalidTimes: Time[] = ["30:00", "23:60", "0:61"] // all emit error
Run Code Online (Sandbox Code Playgroud)

  • 似乎 `"29:00"` 会匹配这种类型 - 所以这不是 100% 正确吗?! (2认同)