typescript - 与 Typescript 等效的 typedef
问题描述
我的应用程序中有各种类型的整数 ID(例如 ProductId、UserId 等),我想实现强类型,以便我可以确定我将正确的 ID 类型传递给方法。
例如,我想声明GetProduct(productId: ProductId)
而不是GetProduct(productId: number)
只有 ProductId 类型的变量可以传递给它。
在我的 C 时代,我会使用 typedef - 例如typedef ProductId int;
在 C# 中,我通过定义一个 ProductId 类来实现这一点,该类具有隐式转换为 int 运算符和显式转换为 int 运算符。比 typedef 更麻烦,但它可以工作。
我试图弄清楚如何在 Typescript 中做同样的事情。对于 TypeScript,我试过这个:
export class ProductId extends Number {}
但这仍然允许传递一个数字来代替 ProductId。
如何在 TypeScript 中实现这一点?
解决方案
可以通过一些努力做到这一点。
诀窍是将您定义ProductID
为在 TS 中与数字不同的东西,但在实际作为 Javascript 运行时仍然是数字。
我在我的博客上写过这个:https ://evertpot.com/opaque-ts-types/
但我将在这里分享重要的细节:
declare const validProductId: unique symbol;
type ProductId = number & {
[validProductId]: true
}
请注意,即使我们声明了一个“唯一符号”,它也完全从 Javascript 中剥离,因此实际上并没有将符号添加到 yourProductId
中,这会很痛苦。
要真正获得一个被识别为 a 的东西ProductId
,您将需要编写一个断言函数、一个类型保护函数,或者只是从一个ProductId
实际允许生成 's 的地方进行强制转换。
再说一遍,实际上不需要将此符号添加到您的ProductId
. 中,这只是为了确保 Typescript 识别ProductId
为与number
. 在运行时,它只是一个number
.
对于您的用例来说,这是一个很好的模式。它基本上是一个标记,表明这不仅仅是任何数字,它特别是一个已经被您的业务逻辑审查为产品 ID 的数字。
推荐阅读
- php - 用PHP上传和显示图片
- spring-boot - 在 Spring Boot 日志记录控制台的开始/结束处需要方括号
- python - 计算空行和列
- servicestack - ServiceStack 结构化日志记录
- java - 如何显示来自另一个类的新 JPanel?
- google-apps-script - 调用 setValues() 时日期更改
- python - pip uninstall tensorflow 抛出 _csv.Error: line contains NUL
- reactjs - 渲染的组件然后消失(react/redux/Firebase)
- oracle - 使用游标在 Oracle SQL 中执行 2 个 for 循环
- javascript - APIRest 文件中的问题通过 node.js 中的 GET