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

如何创建生成嵌套类属性点记法字符串字面量的TypeScript类型?

问题与解决方案

问题背景

AWS SDK导出的AWS对象包含多个客户端(如DynamoDB、ACM),每个客户端同时以类和命名空间的形式存在:

  • DynamoDB命名空间下包含DocumentClient属性
  • ACM命名空间下包含CertificateBody类型

模拟的TypeScript类型定义如下:

class _DocumentClient {}
namespace _DocumentClient {}

// DynamoDB 客户端(将被导入到AWS模块)
declare class _DynamoDB {}
declare namespace _DynamoDB {
  export import DocumentClient = _DocumentClient;
}

// ACM 客户端(将被导入到AWS模块)
declare class _ACM {}
declare namespace _ACM {
  export type CertificateBody = string;
}

// 模拟AWS模块(实际包含更多客户端)
namespace AWS {
  export import ACM = _ACM;
  export import DynamoDB = _DynamoDB;
}

目标是生成一个字符串字面量联合类型,如"DynamoDB.DocumentClient" | "ACM.CertificateBody",但尝试的代码仅能获取到"prototype",无法得到预期的属性名:

// 正常获取客户端名称联合类型:"ACM" | "DynamoDB"
type ClientName = keyof typeof AWS; 

// 预期得到 "DocumentClient" | "CertificateBody",但实际仅能拿到 "prototype"
type NestedClientName<C extends ClientName> = keyof typeof AWS[C]; 

// 期望生成点记名字符串联合类型,但结果不符合预期
type NestedClientFullName<C extends ClientName, NC extends NestedClientName<C>> = `${C}.${NC}`; 

解决方案

问题根源在于typeof AWS[C]指向的是类的构造函数类型,keyof只能获取到构造函数的默认属性(如prototype),而非命名空间下的成员。我们需要直接访问客户端的命名空间类型,才能获取到目标成员。

方法1:手动映射命名空间类型

直接创建客户端命名空间的类型映射,明确关联每个客户端与其命名空间:

// 定义客户端与对应命名空间的类型映射
type AWSClientNamespaces = {
  ACM: typeof _ACM;
  DynamoDB: typeof _DynamoDB;
};

// 获取所有客户端名称
type ClientName = keyof AWSClientNamespaces;

// 获取指定客户端命名空间下的成员键
type NestedClientName<C extends ClientName> = keyof AWSClientNamespaces[C];

// 生成完整的点记名字符串联合类型
type NestedClientFullName = {
  [C in ClientName]: `${C}.${NestedClientName<C>}`;
}[ClientName];

// 验证结果:NestedClientFullName = "ACM.CertificateBody" | "DynamoDB.DocumentClient"
type TestResult = NestedClientFullName;

方法2:利用类型推断自动关联(适配实际AWS SDK)

在实际AWS SDK的类型定义中,客户端的类与命名空间是合并的,命名空间成员会作为类的静态属性存在。此时可以通过typeof AWS[C]的静态属性来获取,但需要过滤掉默认的构造函数属性:

// 获取所有客户端名称
type ClientName = keyof typeof AWS;

// 过滤掉构造函数默认属性,仅保留命名空间成员
type NestedClientName<C extends ClientName> = Exclude<keyof typeof AWS[C], "prototype">;

// 生成完整的点记名字符串联合类型
type NestedClientFullName = {
  [C in ClientName]: `${C}.${NestedClientName<C>}`;
}[ClientName];

说明

  • 第一种方法更直观,适合模拟场景或需要精确控制的情况;
  • 第二种方法适配实际AWS SDK的类型结构,无需手动维护映射关系;
  • 两种方法最终都能生成目标字符串字面量联合类型,满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:08:12