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

如何用TypeScript定义含0-1个URI键值对的对象类型?

可行,具体实现方式如下

1. 定义URI的编译时类型约束

TypeScript无法通过类型系统完全覆盖所有URI格式规范,但可以用模板字面量类型做近似的编译时约束,比如匹配带协议的URI:

// 约束带协议的URI(如 http://xxx、https://xxx、ftp://xxx 等)
type URI = `${string}://${string}`;

2. 实现符合要求的对象类型

要满足「0个或1个属性、键和值均为URI」的约束,可通过联合类型+交叉类型限制属性数量与类型:

// 单属性对象类型:键为URI,值为URI,且不允许额外属性
type SingleURIMap<K extends URI> = { [P in K]: URI } & { [P in Exclude<string, K>]?: never };

// 最终类型:空对象 或 符合要求的单属性对象
type URIMap = {} | SingleURIMap<URI>;

3. 编译时验证示例

// ✅ 合法:空对象
const emptyMap: URIMap = {};

// ✅ 合法:单个URI键+URI值
const validMap: URIMap = {
  "https://example.com": "https://api.example.com"
};

// ❌ 非法:多个属性
const invalidMap1: URIMap = {
  "https://a.com": "https://b.com",
  "https://c.com": "https://d.com"
};

// ❌ 非法:键不是URI
const invalidMap2: URIMap = {
  "example.com": "https://api.example.com"
};

// ❌ 非法:值不是URI
const invalidMap3: URIMap = {
  "https://example.com": "api.example.com"
};

4. 运行时补充校验

TypeScript类型约束仅在编译时生效,若涉及动态生成的对象(如API返回、用户输入),需添加运行时校验逻辑:

// 运行时校验字符串是否为URI
function isURI(str: string): str is URI {
  // 可根据需求调整正则规则,这里是基础的URI匹配
  const uriPattern = /^[a-zA-Z][a-zA-Z0-9+-.]*:\/\/.+/;
  return uriPattern.test(str);
}

// 运行时校验对象是否符合URIMap类型
function isValidURIMap(obj: unknown): obj is URIMap {
  if (typeof obj !== 'object' || obj === null) return false;
  const entries = Object.entries(obj);
  if (entries.length > 1) return false;
  if (entries.length === 0) return true;
  const [key, value] = entries[0];
  return typeof value === 'string' && isURI(key) && isURI(value);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:37:38