首页 > 解决方案 > 与 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 中实现这一点?

标签: typescripttypedef

解决方案


可以通过一些努力做到这一点。

诀窍是将您定义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 的数字。


推荐阅读