TypeScript中如何声明由重复子串组成的字符串类型别名?
TypeScript中声明重复子串组成的字符串类型别名
问题背景
你已经定义了表示WKT坐标的类型:
type WicketCoordinates = `${number} ${number}` | `${number} ${number} ${number}`;
现在需要创建支持1个或多个WicketCoordinates子串通过逗号分隔的字符串类型,用于LineString这类几何体,但直接自循环的写法会触发类型循环引用错误。
解决方案
1. TypeScript 4.5+:递归模板字符串类型(推荐)
从TypeScript 4.5版本开始,官方支持递归模板字符串类型,你最初的写法在新版本中是可行的,不会再触发循环引用错误:
type WicketCoordinates = `${number} ${number}` | `${number} ${number} ${number}`; type WicketCommaSeparatedCoordinates = WicketCoordinates | `${WicketCoordinates},${WicketCommaSeparatedCoordinates}`; // 验证示例 const a: WicketCommaSeparatedCoordinates = "12 34"; // 合法 const b: WicketCommaSeparatedCoordinates = "12 34,56 78"; // 合法 const c: WicketCommaSeparatedCoordinates = "12 34,56 78,90 12"; // 合法 const d: WicketCommaSeparatedCoordinates = "12 34,56 78,90 12,34 56"; // 合法
这种写法可以支持任意数量(受限于TypeScript默认递归深度,通常约100层)的坐标子串。
2. 旧版本TypeScript:有限长度的类型生成
如果你的TypeScript版本低于4.5,只能通过元组辅助的方式生成有限长度的坐标串类型,示例如下:
type WicketCoordinates = `${number} ${number}` | `${number} ${number} ${number}`; // 递归生成最多N个坐标的逗号分隔串 type WicketCommaSeparatedCoordinates< MaxLength extends number, Current extends WicketCoordinates[] = [] > = Current['length'] extends MaxLength ? Current[number] : WicketCoordinates | `${WicketCoordinates},${WicketCommaSeparatedCoordinates<MaxLength, [...Current, WicketCoordinates]>}`; // 生成最多支持5个坐标的类型 type LineStringCoords = WicketCommaSeparatedCoordinates<5>; // 验证示例 const valid1: LineStringCoords = "12 34"; // 合法 const valid3: LineStringCoords = "12 34,56 78,90 12"; // 合法 const invalid6: LineStringCoords = "12 34,56 78,90 12,34 56,78 90,11 22"; // 报错(超过5个坐标)
这种方式需要指定最大支持的坐标数量,超出后会触发类型错误。
内容的提问来源于stack exchange,提问作者Farhad Rad
相关产品推荐
相关产品推荐

