资讯详情

资讯详情

Dagger TypeScript SDK ListTypeDef 类详解:模块列表类型定义与元素类型获取

Dagger TypeScript SDK ListTypeDef 类详解模块列表类型定义与元素类型获取【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/daggerListTypeDef 是 Dagger 模块类型系统TypeDef中专门描述列表类型的客户端类用于表示模块函数参数或返回值中由同一类型元素组成的数组。本文以dagger.io/daggerTypeScript SDK 的 ListTypeDef 类文档 为骨架结合仓库内 Go 端核心实现与 SDK 生成源码讲清该类的构造方式、两个核心方法、与TypeDefKind.LIST_KIND的配对关系以及如何在模块定义中创建和消费列表类型帮助你写出结构正确的 Dagger 模块类型声明。ListTypeDef 在 Dagger 类型体系中的位置Dagger 模块通过TypeDef描述其公开 API 的参数类型与返回类型而ListTypeDef是其中专门承载列表语义的一环。官方文档给出的定义是A definition of a list type in a Module.模块中列表类型的定义在 TypeDefKind 枚举 中List成员的取值为LIST_KIND其说明明确了这种配对关系Always paired with a ListTypeDef. A list of values all having the same type.始终与 ListTypeDef 配对。一组类型完全相同的值构成的列表。这意味着一个类型为列表的TypeDef其kind字段一定是LIST_KIND并且会通过asList()返回对应的ListTypeDef对象。整个 TypeDef 家族还包括ObjectTypeDef、ScalarTypeDef、EnumTypeDef、InterfaceTypeDef、InputTypeDef等分别对应TypeDefKind中的OBJECT_KIND、SCALAR_KIND、ENUM_KIND、INTERFACE_KIND、INPUT_KIND。从 Go 端核心实现看core/typedef.go 中的结构体非常简洁type ListTypeDef struct { ElementTypeDef dagql.ObjectResult[*TypeDef] } func (*ListTypeDef) Type() *ast.Type { return ast.Type{ NamedType: ListTypeDef, NonNull: true, } } func (*ListTypeDef) TypeDescription() string { return A definition of a list type in a Module. }可见列表类型的全部信息就是其元素类型ElementTypeDef——列表本身的语义同类型元素的集合由类型系统固化无需额外字段。GraphQL 类型名与描述也与 TypeScript 文档一一对应。类继承与构造仅供内部使用的 BaseClient 子类ListTypeDef继承自BaseClient构造签名如下new ListTypeDef(ctx?: Context, _id?: ListTypeDefID): ListTypeDef文档明确标注Constructor is used for internal usage only, do not create object from it.构造函数仅供内部使用请勿手动创建该对象。这与 Dagger TypeScript SDK 的生成代码一致。在 sdk/typescript/src/api/client.gen.ts 中export class ListTypeDef extends BaseClient { private readonly _id?: ID undefined constructor(ctx?: Context, _id?: ID) { super(ctx) this._id _id } // ... }日常开发中你不会直接new ListTypeDef()而是通过两条路径间接获得实例从TypeDef.asList()转换得到——当某个TypeDef的kind为LIST_KIND时asList()返回其列表专属定义通过TypeDef.withListOf(elementType)创建列表类型随后在 GraphQL 查询中携带elementTypeDef字段反序列化后得到ListTypeDef。这与文档中Extends BaseClient以及构造参数_id可选的ListTypeDefID的设定是自洽的_id用于在客户端持有已知标识时直接返回结果、避免重复查询见下文id()实现。核心方法一elementTypeDef()——获取列表元素类型elementTypeDef()是ListTypeDef上最有业务价值的访问器elementTypeDef():TypeDefThe type of the elements in the list.列表中元素的类型。它返回一个完整的TypeDef因此你可以继续对其链式调用kind()、optional()、asObject()、asScalar()等方法深入探查元素的具体形态。例如列表元素是标量如string则返回的TypeDef.kind()为STRING_KIND列表元素是对象则asObject()能拿到对象的字段与函数定义列表元素本身又是一个列表嵌套数组则kind()为LIST_KIND可以继续asList()递归下钻。在生成的 TS 代码中该方法只是选择 GraphQL 的elementTypeDef字段并返回新的TypeDef包装client.gen.tselementTypeDef (): TypeDef { const ctx this._ctx.select(elementTypeDef) return new TypeDef(ctx) }Go 端则通过 module_typedef_canonical.go 的解析函数直接把typeDef.AsList暴露为 GraphQL 字段func (s *moduleSchema) typeDefAsList( ctx context.Context, typeDef *core.TypeDef, _ struct{}, ) (dagql.Nullable[dagql.ObjectResult[*core.ListTypeDef]], error) { return typeDef.AsList, nil }需要说明的是从 TS 源码看elementTypeDef的返回值虽然是非空的对象引用但若查询上下文中ListTypeDef由asList()派生且类型并非LIST_KIND实际取到的AsList为 null——这与 TypeDef.asList() 文档 中若 kind 不是 LIST 则返回 null的语义保持一致使用时应当先通过kind()判断类型再下钻。核心方法二id()——ListTypeDefID 唯一标识符第二个公开方法是id()id():PromiseListTypeDefID A unique identifier for this ListTypeDef.该 ListTypeDef 的唯一标识符。ListTypeDefID是 Dagger 为每个ListTypeDef实例生成的不透明标识符类型其定义为string objectListTypeDefID 文档带有一个__ListTypeDefID: never的私有标记字段用于在类型层面防止与其他 ID 类型如TypeDefID、ObjectTypeDefID混用——这是 Dagger SDK 常见的不透明标量opaque scalar模式。SDK 生成实现client.gen.ts带有_id短路缓存id async (): PromiseID { if (this._id) { return this._id } const ctx this._ctx.select(id) const response: AwaitedID await ctx.execute() return response }即若对象构造时已携带_id直接返回不发网络请求否则向引擎发起id字段查询。这类 ID 通常用于把类型定义作为参数传给引擎侧 API例如模块配置、持久化或跨调用引用。在 Go 端ListTypeDef实现了 dagql.HasDependencyResults 接口并具备持久化编解码能力EncodePersistedObject/DecodePersistedObject见 core/typedef.go配合persistedListTypeDef结构体core/typedef.go实现列表类型定义在引擎缓存与持久化存储之间的序列化——这正是ListTypeDefID能被跨会话引用和恢复的底层支撑。如何创建 ListTypeDefTypeDef.withListOf() 与 asList()虽然不能直接 new但构建一个列表类型定义非常直观。在 TypeScript SDK 中TypeDef提供withListOf(elementType:TypeDef):TypeDefReturns a TypeDef of kind List with the provided type for its elements.生成代码client.gen.ts将elementType作为 GraphQL 参数提交返回新的TypeDef其kind为LIST_KINDAsList指向新的ListTypeDefwithListOf (elementType: TypeDef): TypeDef { const ctx this._ctx.select(withListOf, { elementType }) return new TypeDef(ctx) }Go 端对应实现位于 core/typedef.gofunc (typeDef *TypeDef) WithListOf(list dagql.ObjectResult[*ListTypeDef]) *TypeDef { typeDef typeDef.WithKind(TypeDefKindList) typeDef.AsList dagql.NonNull(list) return typeDef.syncName() }即把kind置为TypeDefKindListLIST_KIND把AsList指向元素类型的ListTypeDef并同步syncName()生成对应的类型名。反过来从已有TypeDef取列表定义时用asList()其 GraphQL 解析器即上文typeDefAsList。实战示例在模块定义中声明字符串数组类型在 Dagger 模块的 Go/Python/TS SDK 中声明函数签名时会自动生成此类类型但当你通过dag.TypeDef()以编程方式构造模块 API例如编写模块元数据或动态 schema时可以这样描述字符串数组import { dag } from dagger.io/dagger // 方式一基于标量类型构建 const stringType new dag.TypeDef().withScalar(string) const stringListType stringType.withListOf(stringType) // kind LIST_KIND // 方式二基于已存在的元素 TypeDef 直接派生 const fileType new dag.TypeDef().withObject(File) const fileListType fileType.withListOf(fileType) // 读取元素类型得到的就是上面的元素 TypeDef const element: TypeDef fileListType.asList().elementTypeDef()在引擎内部这两步分别对应 core/typedef.go 的WithElementTypeDef克隆式更新保留不可变性、不修改原对象与ListTypeDef的字段组装func (typeDef *ListTypeDef) WithElementTypeDef(elementTypeDef dagql.ObjectResult[*TypeDef]) *ListTypeDef { typeDef typeDef.Clone() typeDef.ElementTypeDef elementTypeDef return typeDef }ListTypeDef 与 TypeDef 家族的对照关系TypeDef.kind 取值配对的对象类从 TypeDef 获取的访问器语义LIST_KINDListTypeDef本文主题asList()同类型元素的列表OBJECT_KINDObjectTypeDefasObject()带字段与函数的具名对象SCALAR_KINDScalarTypeDefasScalar()基础标量ENUM_KINDEnumTypeDefasEnum()GraphQL 枚举及其取值INTERFACE_KINDInterfaceTypeDefasInterface()可被对象/接口实现的方法集合INPUT_KINDInputTypeDefasInput()GraphQL 输入类型完整的asList、asObject、asScalar、asEnum、asInterface、asInput访问器签名可对照 TypeDef 类文档其中asList()的返回类型正是ListTypeDef进一步印证二者kind 配对、访问器互指的关系。测试侧core/typedef_test.go也通过构造sampleListTypeDef验证了该对象的生成与解析链路。小结ListTypeDef虽然只有两个公开方法却是 Dagger 模块类型定义中列表语义的载体elementTypeDef()让你拿到列表元素的TypeDef进而支持任意深度的类型下钻标量、对象、枚举乃至嵌套列表id()提供不透明的ListTypeDefID标识支撑类型定义在引擎内的持久化与跨会话引用列表类型不通过构造函数创建而是由TypeDef.withListOf(elementType)生成、经asList()取回kind恒为LIST_KINDGo 端核心实现core/typedef.go与 TS 生成代码sdk/typescript/src/api/client.gen.ts在结构、描述与行为上完全对齐。理解了这条TypeDef → ListTypeDef → elementTypeDef的链路你就能在 Dagger 模块开发中准确构造和解析数组类型的参数与返回值也能在阅读模块 schema 或调试模块元数据时快速定位类型定义的真实结构。【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →