typescript类型体操--驼峰下划线互转

需求

1.对于给定下划线形式的字符串类型T,实现一个泛型CamelCase,返回驼峰形式的类型G。

2.对于给定驼峰形式的字符串类型G,实现一个泛型UnderlineCase,返回下划线形式的类型T。

typescript 复制代码
type camelCaseResult = CamelCase<'hello_my_love'> // expected to 'helloMyLove'
typescript 复制代码
type UnderlineCaseResult = 
UnderlineCase<'helloMyLove'> // expected to 'hello_my_love'

前置知识

分析

CamelCase

对于下划线转小驼峰,我们实际需要转换的字符串中可能的单词个数(以_分隔)是不定的,为此,我们该操作会涉及到递归,递归终止条件为剩余子串是否含有_。

使用extends做类型约束时,我们可以结合ts类型推断中使用模版字符串加infer关键字指定局部变量。

在我的观察中,推断时,除非指定非字母的分隔符,否则推断中每次匹配都将把字符串按单个字母拆分,以下就是一个例子:

typescript 复制代码
type ITest<Str extends string> = Str extends `${infer A}_${infer B}${infer C}`
    ? `A-(${A})/B-(${B})/C-(${C})` : Str

于是我们extends约束的类型为

typescript 复制代码
`${infer First}_${infer Second}${infer Rest}`

以'hello_my_love'为例,首次匹配时:

typescript 复制代码
First -- 'hello';
Second -- 'm'
Rest -- "y_love"

显而易见地,hello不需要处理,m需要转为M,y_love则进入到下一次匹配中(递归操作)。

第二次匹配时:

typescript 复制代码
First -- 'y';
Second -- 'l'
Rest -- "ove"

因此,CamelCase这个泛型为:

typescript 复制代码
type CamelCase<Str extends string> =
    Str extends `${infer First}_${infer Second}${infer Rest}`
        ? `${First}${Uppercase<Second>}${CamelCase<Rest>}`
        : Str

UnderlineCase

易知,关键是识别出helloMyLove中的M和L,但ts的类型推断中似乎并没有已存在的类型判断某个字母是否是大写字母,只好手写了:

typescript 复制代码
type UpperLetter = 'A'|'B'|'C'
    |'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'
    |'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'

按照Camelcase中的思路,约束类型可以为:

typescript 复制代码
`${infer First}${infer Upper}${infer Rest}`

第一次匹配时:

typescript 复制代码
First -- 'h'
Upper -- 'e'
Rest -- 'lloMyLove'

第二次匹配时:

typescript 复制代码
First -- 'l'
Upper -- 'l'
Rest -- 'oMyLove'

第三次匹配时:

typescript 复制代码
First -- 'o'
Upper -- 'M'
Rest -- 'yLove'

...

我们应该做的应该是把大写字母M和L分别转为_m和_l,因此,新建一个类型UnderlineChar实现:

typescript 复制代码
type UnderlineChar<Str extends string> =
    Str extends UpperLetter
        ? `_${Lowercase<Str>}`
        : Str

最终的结果为:

typescript 复制代码
type UnderlineCase<Str extends string> =
    Str extends `${infer First}${infer Upper}${infer Rest}`
        ? `${UnderlineChar<First>}${UnderlineChar<Upper>}${UnderlineCase<Rest>}`
        : Str

应用场景

CamelCase

typescript 复制代码
function toCamelString<T extends string,>(str:T):CamelCase<T>
function toCamelString(str){
    return str.replace(/_(\w)/g, function(_, letter){
        return letter.toUpperCase();
    });
}

UnderlineCase

typescript 复制代码
function toUnderlineString<T extends string>(str:T):UnderlineCase<T>
​
function toUnderlineString(str:string){
    return str.replace(/([A-Z])/g,function (_,letter){
        return '_'+letter.toLowerCase()
    })
}
相关推荐
孟陬1 天前
Foobar 技术周刊#160:大模型让大规模形式化软件验证成为现实丨AI写C++代码之后会发生什么?丨我们真的需要alpha() 函数吗丨重试,有时会让故障更
前端·后端·typescript
螺丝钉tina2 天前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
华玥作者2 天前
Vue 3 + TypeScript + uni-app 组件库推荐:hy-app(华玥组件库)
vue.js·typescript·uni-app
Momo__3 天前
你写的 import 重试,从来没生效过
前端·javascript·typescript
长不大的杨瑞杰4 天前
OpenCode v2 Custom Tools 实战:开发数据库、工单与发布工具
人工智能·typescript·开发工具·opencode·custom tools
shmily麻瓜小菜鸡4 天前
TypeScript 知识点补充(第三部分:工程化与高级类型)
前端·javascript·typescript
腾科IT教育4 天前
TypeScript 泛型(Generics):类型占位符实现复用与安全
安全·typescript·泛型
猫头_5 天前
MCP 开发实战:把你自己的后端 API 接入 Agent
人工智能·typescript·mcp
长不大的杨瑞杰5 天前
OpenCode v2 LSP 实战:内置语言服务器、自定义配置与诊断闭环
java·人工智能·typescript·lsp·opencode
Highcharts.js5 天前
Highcharts 集成到 React 或 Vue 项目中时,如何高效地使用 TypeScript技巧?
vue.js·人工智能·react.js·typescript·前端框架·highcharts