如何用TypeScript声明特定字符串结构的对象类型?
解决方法
要实现你要的类型约束,核心思路是用TypeScript泛型+字符串字面量类型转换,既约束id的格式,又强制upperID和camelID与id保持格式对应。
分两种场景处理(根据你注释和例子的矛盾)
你注释里说id是帕斯卡命名(比如MyId),但例子里写的是蛇形命名(my_id),这里分两种情况给出方案:
场景1:id确实是帕斯卡命名(首字母大写、单词首字母大写、无下划线)
比如id: 'MyUserId',对应的upperID是'MY_USER_ID',camelID是'myUserId'。
先定义类型工具函数,再创建主类型:
// 约束帕斯卡命名的类型(用品牌类型避免普通字符串混入) type PascalCase = string & { __brand: 'PascalCase' }; // 把帕斯卡命名转成全大写蛇形(比如 MyId → MY_ID) type PascalToUpperSnake<T extends string> = T extends `${infer First}${infer Rest}` ? Rest extends Uncapitalize<Rest> ? `${Uppercase<First>}${PascalToUpperSnake<Rest>}` : `${Uppercase<First>}_${PascalToUpperSnake<Rest>}` : ''; // 把帕斯卡命名转成小驼峰(比如 MyId → myId) type PascalToCamel<T extends string> = Uncapitalize<T>; // 主类型:泛型接收帕斯卡字符串,自动推导其他字段类型 type IDObject<T extends PascalCase> = { id: T; upperID: PascalToUpperSnake<T>; camelID: PascalToCamel<T>; };
使用示例:
// 完全符合约束的对象(不会报错) const validObj: IDObject<'MyUserId'> = { id: 'MyUserId', upperID: 'MY_USER_ID', camelID: 'myUserId' }; // 错误示例1:id不是帕斯卡命名(比如用了下划线) const invalidId: IDObject<'my_user_id'> = { /* 这里会报错,因为'my_user_id'不符合PascalCase约束 */ }; // 错误示例2:upperID格式不匹配 const invalidUpper: IDObject<'MyUserId'> = { id: 'MyUserId', upperID: 'MYUSERID', // 报错,必须是'MY_USER_ID' camelID: 'myUserId' };
场景2:id是蛇形命名(和你例子一致,比如my_id)
如果是这种情况,调整类型工具函数即可:
// 约束蛇形命名的类型(小写字母+下划线分隔) type SnakeCase = string & { __brand: 'SnakeCase' }; // 蛇形转全大写蛇形(直接转大写就行) type SnakeToUpperSnake<T extends SnakeCase> = Uppercase<T>; // 蛇形转小驼峰(比如 my_id → myId) type SnakeToCamel<T extends SnakeCase> = T extends `${infer First}_${infer Rest}` ? `${First}${Capitalize<SnakeToCamel<Rest>>}` : T; // 主类型 type IDObject<T extends SnakeCase> = { id: T; upperID: SnakeToUpperSnake<T>; camelID: SnakeToCamel<T>; };
使用示例:
// 完全符合你例子的对象 const myObject: IDObject<'my_id'> = { id: 'my_id', upperID: 'MY_ID', camelID: 'myId' }; // 错误示例:camelID格式不对 const invalidCamel: IDObject<'my_id'> = { id: 'my_id', upperID: 'MY_ID', camelID: 'MyId' // 报错,必须是'myId' };
为什么这么做?
- 品牌类型约束:用
__brand标记特定格式的字符串,避免不符合要求的字符串赋值给id。 - 泛型+字面量转换:让TypeScript自动推导
upperID和camelID的正确格式,一旦id变化,其他字段的类型也会跟着更新,同时强制格式匹配,不会出现手动写错的情况。
内容的提问来源于stack exchange,提问作者passionateLearner
相关产品推荐
相关产品推荐

