TypeSpec 值(Value)体系完全指南:对象值、数组值、标量值与 `valueof` 约束
TypeSpec 值Value体系完全指南对象值、数组值、标量值与valueof约束【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespecTypeSpec 语言在类型系统之外提供了一套独立的“值Value”体系用于表达默认值、示例数据、装饰器参数与模板实参。本篇以 语言基础文档 values.md 为骨架系统讲解四种值类型、字面量与上下文的语义切换、const声明、typeof运算符、值校验以及枚举成员/联合变体引用规则并深入 编译器源码 印证其底层实现。读完本文你将能准确判断一段字面量“何时是类型、何时是值”并熟练用#{}、#[]、标量构造函数与valueof写出正确的 TypeSpec 代码。值Value与类型Type两个相互独立的世界TypeSpec 除了可以定义类型还可以定义值。在 API 描述中值主要用在四个场景为类型定义默认值如属性默认值提供示例值如example向装饰器传参如maxItems(2)中的2作为最终会传给装饰器或被用作默认值的模板参数。核心规则是值不能当作类型使用类型也不能当作值使用二者是完全分离的两个实体。例如下面的代码是错误的const example #{ prop1: #{ nested: true }, // ok对象值属性必须指向另一个值 prop2: { nested: true, }, // error模型表达式是类型不能放在对象值里 prop3: string, // errorstring 是类型不能作为对象值属性 };不过有两类“特殊存在”可以根据上下文在类型与值之间切换标量字面量string / number / boolean / null 字面量视所处上下文不同可能是一个类型或一个值见下文 标量字面量枚举成员引用与联合变体引用同样视上下文在类型与值之间切换见下文 枚举成员与联合变体引用。在编译器的类型模型中这一分离体现在 types.ts 中定义的Value联合类型它由ScalarValue | NumericValue | StringValue | BooleanValue | ObjectValue | ArrayValue | EnumValue | NullValue | FunctionValue组成与Type联合类型并列为两棵独立的实体树。值的四种基本形态Value kinds值共有四种基本形态对象值object、数组值array、标量值scalar与null分别通过对象值语法、数组值语法、标量字面量/标量构造函数和null字面量创建。此外引用枚举成员与联合变体也会产生值。对象值Object values#{}对象值使用#{}语法可定义任意数量的属性const point #{ x: 0, y: 0 };对象值的每个属性必须引用其他值引用类型如模型、string都是编译错误。其底层结构见 types.tsObjectValue内部通过Mapstring, ObjectValuePropertyDescriptor保存属性名到属性值value: Value的映射ObjectValuePropertyDescriptor还记录了可选的 AST 节点便于诊断定位。数组值Array values#[]数组值使用#[]语法可包含任意数量的元素const points #[#{ x: 0, y: 0 }, #{ x: 1, y: 1 }];与对象值一样数组值内部不能包含类型。ArrayValue在 types.ts 中定义为values: Value[]元素同样只能是值。如果数组类型通过minValue/maxValue以及更常见的minItems/maxItems声明了最小/最大元素个数编译器会在给该类型赋数组值时做数量校验/** Can have at most 2 tags */ maxItems(2) model Tags is Arraystring; const exampleTags1: Tags #[TypeSpec, JSON]; // ok const exampleTags2: Tags #[TypeSpec, JSON, OpenAPI]; // error超出最大元素数这些校验装饰器定义于 std/decorators.tsp其参数声明为valueof integerminItems/maxItems或valueof RangeLimitableTypesminValue/maxValue即要求调用方传入值而非类型。标量值Scalar values创建标量值有两种方式字面量语法如string value与标量构造函数如utcDateTime.fromISO(2020-12-01T12:00:00Z)。标量字面量字符串、数值、布尔与null的字面量会根据所在上下文被解释为类型或值类型上下文type context模型属性类型、操作返回类型、别名定义等位置字面量成为字面量类型literal type例如model A { x: 123 }中的123是数值字面量类型值上下文value context默认值、对象值的属性、const定义等位置字面量成为值模糊上下文ambiguous context模板或装饰器参数可同时接受类型或值中字面量默认解释为值如需在此时把它显式作为类型传递可使用typeof运算符转换。下面的示例展示了三种上下文对装饰器实参的影响// 示例装饰器签名仅为演示无实际实现。 extern dec setNumberValue(target: unknown, color: valueof numeric); extern dec setNumberType(target: unknown, color: numeric); extern dec setNumberTypeOrValue(target: unknown, color: numeric | (valueof numeric)); setNumberValue(123) // 传入标量值 numeric(123) setNumberType(123) // 传入数值字面量类型 123 setNumberTypeOrValue(123) // 模糊上下文 → 传入标量值 numeric(123) model A {}从实现上看字面量节点在检查check阶段先被求值为一种“不定态Indeterminate”再由约束决定落到类型还是值分支。核心逻辑在 checker.ts 的getValueForNode与 getValueFromIndeterminate对于String/Number/Boolean/EnumMember/UnionVariant/null等既可以当类型又可以当值的实体会依据CheckValueConstraint决定是否转为值。若在期望值的位置传入了纯类型编译器会抛出expect-value诊断其消息会给出修正建议见 messages.ts${name} refers to a model type, but is being used as a value here. Use #{} to create an object value.Is a tuple type, but is being used as a value here. Use #[] to create an array value.这也解释了为何模型表达式{ nested: true }报错而对象值#{ nested: true }合法——编译器甚至提供了把{}自动修正为#{}、把元组自动修正为#[]的 code fix。标量构造函数标量构造函数通过“在标量引用后加括号”的方式创建标量值。对于从numeric、string、boolean派生的标量直接调用即可const n int8(100); const s string(hello);任何标量还可以声明具名构造函数named constructor接收一个或多个值参数。例如utcDateTime提供了接收 ISO 字符串的fromISO构造函数。自定义具名构造函数用init关键字声明scalar ipv4 extends string { init fromInt(value: uint32); } const ip ipv4.fromInt(2341230);内置的时间类标量都预置了具名构造函数定义见 intrinsics.tsp标量构造函数示例plainDatefromISO/nowplainDate.fromISO(2024-05-06)plainTimefromISO/nowplainTime.fromISO(12:34)utcDateTimefromISO/nowutcDateTime.fromISO(2024-05-06T12:20-12Z)offsetDateTimefromISO/nowoffsetDateTime.fromISO(2024-05-06T12:20-0700)durationfromISOduration.fromISO(P1Y1D)在检查器层面createScalarValue见 checker.ts负责核对实参个数必选参数、可选参数、rest 参数、逐一以valueof约束求值实参并对个数不匹配的情况报告invalid-argument-count诊断。而像 examples.ts 这样的下游模块则通过value.value.name fromISO判断并序列化这些构造函数产生的值。Null 值null值通过null字面量创建const value: string | null null;null值与null类型一样在 TypeSpec 语言中没有任何特殊行为它仅仅是像 JSON 中那样的null值。在类型模型中对应 NullValue其value字段恒为null。Const 声明const声明把值保存到变量中供后续引用。const可以带可选类型注解当类型注解缺省时编译器会从初始化式构造一个精确类型exact type作为推断类型const stringValue: string hello; // ^-- type: string const oneValue 1; // ^-- type: 1 const objectValue #{ x: 0, y: 0 }; // ^-- type: { x: 0, y: 0 }可见无注解的const oneValue 1推断出的类型是字面量类型1而非numeric#{ x: 0, y: 0 }推断为{ x: 0, y: 0 }。带注解的const则按注解类型存储如string。const节点的检查逻辑见 checker.ts先对初始化式求值若提供了类型注解则校验值可赋给该类型并通过copyValue(value, { type })把注解类型记录为值的存储类型storage type。typeof运算符typeof运算符返回某个值引用的声明类型或推断类型。注意变量实际存储的值可能比声明类型更具体——例如用联合类型声明的const其值在任意时刻只会是联合中的某一个变体但typeof返回的是声明的联合类型const stringValue: string hello; // typeof stringValue 返回 string const oneValue 1; // typeof oneValue 返回 1 const stringOrOneValue: string | 1 1; // typeof stringOrOneValue 返回 string | 1在模糊上下文中typeof也是把“被当作值的字面量”显式恢复为类型的常用手段与 标量字面量 一节中的setNumberType(123)场景互补。值校验ValidationTypeSpec 会用minLength、maxValue等内置校验装饰器对值进行验证。校验既作用于直接赋值的const也递归作用于对象值/数组值内部的元素maxLength(3) scalar shortString extends string; const s1: shortString abc; // ok const s2: shortString abcd; // error超过最大长度 model Entity { a: shortString; } const e1: Entity #{ a: abcd }; // error对象值内层属性同样参与校验这类装饰器在 std/decorators.tsp 中均声明为valueof参数如extern dec maxLength(target: string | ModelProperty, value: valueof integer)即它们接收的是值。编译器在赋值检查路径checkValueOfType见 checker.ts之外还会对值执行约束校验从而保证默认值、示例值与装饰器参数在编译期即符合类型声明的约束。枚举成员与联合变体引用枚举成员引用遵循与标量字面量相同的上下文规则在类型上下文中引用成为枚举成员类型Reflection.EnumMember在值上下文或模糊上下文中引用成为该成员对应的值。extern dec setColorValue(target: unknown, color: valueof string); extern dec setColorMember(target: unknown, color: Reflection.EnumMember); enum Color { red, green, blue, } setColorValue(Color.red) // 等价于传入字面量 red setColorMember(Color.red) // 传入枚举成员 Color.red model A {}联合变体引用的规则类似类型上下文得到该变体的类型值上下文或模糊上下文得到该变体的值。但有一条硬性限制引用其类型不是字面量类型的联合变体作为值使用是错误因为无法把任意类型降级成一个具体的值。extern dec setColorValue(target: unknown, color: valueof string); extern dec setColorType(target: unknown, color: string); union Color { red: red, green: green, blue: blue, other: string, // 类型不是字面量 } setColorValue(Color.red) // 传入标量值 string(red) setColorValue(Color.other) // error试图把类型当值传递 setColorType(Color.red) // 传入字符串字面量类型 red model A {}从 checker.ts 可以看到getValueFromIndeterminate对UnionVariant的处理是递归下钻到其底层类型再判断若底层是String/Number/Boolean等可值化的字面量类型则成功转为值否则维持类型原样并在后续的期望值检查中报错。结合测试验证valueof如何把值传给装饰器编译器测试 decorators.test.ts 直接验证了值到 JS 实参的转换行为// valueof {name: string} #{name: foo} → JS 对象 { name: foo } // valueof {name: unknown} #{name: #{other: foo}} → 递归转换为 { name: { other: foo } } // valueof string[] #[foo] → JS 数组 [foo] // valueof unknown[] #[#[foo]] → 递归转换为 [[foo]]测试还覆盖了__proto__、constructor等特殊属性名的安全性对象值在转换为 JS 对象时这些成员仍保留为自有属性避免原型污染说明对象值到运行时数据的序列化是递归且安全的。这从侧面印证了值体系不仅是语法糖还承担着“把声明式数据安全地交给装饰器实现”的职责。小结TypeSpec 的值体系可以概括为三点语法上用#{}写对象值、用#[]写数组值、用字面量与标量构造函数写标量值、用null写空值语义上标量字面量、枚举成员与联合变体引用会根据类型/值/模糊上下文自动切换身份typeof用于显式取回类型用途上值服务于默认值、示例、装饰器实参与模板实参并由minLength、maxItems、minValue等内置装饰器在编译期完成校验。理解并善用这套体系是写出规范、可验证的 TypeSpec API 描述的关键一步。【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Linux驱动自动加载机制详解:从modprobe到设备树与udev

Linux驱动自动加载机制详解:从modprobe到设备树与udev

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 1:48:32 阅读更多 →
Material Design Lite Snackbar 组件实战指南:从 Markup 结构到源码级消息队列机制

Material Design Lite Snackbar 组件实战指南:从 Markup 结构到源码级消息队列机制

Material Design Lite Snackbar 组件实战指南:从 Markup 结构到源码级消息队列机制 【免费下载链接】material-design-lite Material Design Components in HTML/CSS/JS 项目地址: https://gitcode.com/gh_mirrors/ma/material-design-lite Material Design …

2026/9/19 1:48:32 阅读更多 →
医用内窥镜图像处理与市场分析:从光学链路到可复现脚本

医用内窥镜图像处理与市场分析:从光学链路到可复现脚本

简介:这份2024医用内窥镜行业研究报告以PPT形式呈现,面向医疗器械行业研究者、投资分析人员及企业战略规划者,帮助读者快速把握行业全貌与市场机遇。报告围绕行业概述、市场分析、竞争格局、发展趋势与挑战四大板块展开,系统梳理了…

2026/9/19 1:48:32 阅读更多 →

最新新闻

ISO 17021-10审核员能力评估:从危险源辨识到持续适任的完整框架

ISO 17021-10审核员能力评估:从危险源辨识到持续适任的完整框架

简介:ISO IEC TS 17021-10:2018《职业健康与安全管理系统的审核和认证能力要求》完整英文版,面向从事OH&S MS审核、认证及相关合规工作的专业人士。规范系统规定了审核员与认证机构的知识、技能、经验、道德行为及持续发展要求,涵盖范围、…

2026/9/19 2:32:58 阅读更多 →
Android RS-485通信实战:解决阻塞读取与方向控制两大深坑

Android RS-485通信实战:解决阻塞读取与方向控制两大深坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 2:32:58 阅读更多 →
Matlab实现莱斯信道下QPSK仿真与星座图畸变分析

Matlab实现莱斯信道下QPSK仿真与星座图畸变分析

简介:本资源是一份面向通信工程专业学生、无线通信方向研究者及Matlab仿真初学者的实践型教学文档,聚焦莱斯信道下QPSK信号传输特性的建模与仿真分析。文档系统讲解了移动无线信道分类、小尺度衰落机理、瑞利与莱斯分布的物理意义及K因子对误比特率的影响…

2026/9/19 2:32:58 阅读更多 →
Java安卓外卖订餐系统课程设计实战:从选型到订单状态机

Java安卓外卖订餐系统课程设计实战:从选型到订单状态机

简介:面向Java/Android学习者的外卖订餐系统课程设计报告,完整记录了从需求分析到项目落地的全过程。文档以软件工程规范为纲,先阐述课程设计目的与任务,再展开需求分析,包含数据流图、用例图、时序图、活动图等建模内…

2026/9/19 2:32:58 阅读更多 →
国产MQTT协议栈选型指南:从License合规到边缘性能实战

国产MQTT协议栈选型指南:从License合规到边缘性能实战

1. 项目概述:为什么国产 MQTT 协议栈不是“换个名字”,而是架构级的重新选择最近三个月,我连续接手了四个工业物联网项目,客户提的需求高度一致:“能不能不用 Mosquitto 或 EMQX?最好用国产的。”起初我以为…

2026/9/19 2:32:58 阅读更多 →
GTM与GA4事件追踪实战:从埋点原理到排错技巧全解析

GTM与GA4事件追踪实战:从埋点原理到排错技巧全解析

做网站分析这一行,埋点永远是个绕不开的活儿。刚入行那会儿,我最烦的就是为了一两个按钮统计去麻烦开发改代码,提个需求排期三五天,改完上线再等数据积累,黄花菜都凉了。后来开始用GTM统一管理GA的追踪代码&#xff0c…

2026/9/19 2:31:58 阅读更多 →

日新闻

BP神经网络时序预测:滑窗长度与多窗口平均策略

BP神经网络时序预测:滑窗长度与多窗口平均策略

简介:面向机器学习、深度学习与数据建模学习者的一份完整研究文献,聚焦BP神经网络在农业产量预测中的应用。文档以1980—2018年全国棉花产量为样本,系统讲解数据归一化处理、激活函数原理、多层神经网络结构搭建及训练流程,展示敏…

2026/9/19 0:00:30 阅读更多 →
Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

上个月调一个Deformable DETR模型,在单卡上要跑将近两天。第二天早上我下意识打开终端翻日志,发现loss从凌晨两点就开始往上爬,一路从0.8涨到1.35,整整六个小时没人发现。那六个小时的训练不仅白跑,还霸占着卡——等于…

2026/9/19 0:00:30 阅读更多 →
OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南 【免费下载链接】opencloud 🌤️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign. 项目地址: htt…

2026/9/19 0:00:30 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/16 19:03:19 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/17 7:57:36 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/17 10:19:14 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/16 22:31:27 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/15 21:39:18 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/16 22:32:59 阅读更多 →