You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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'
};

为什么这么做?

  1. 品牌类型约束:用__brand标记特定格式的字符串,避免不符合要求的字符串赋值给id。
  2. 泛型+字面量转换:让TypeScript自动推导upperID和camelID的正确格式,一旦id变化,其他字段的类型也会跟着更新,同时强制格式匹配,不会出现手动写错的情况。

内容的提问来源于stack exchange,提问作者passionateLearner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:55:24