繁体   English   中英

TypeScript 中是否可以使用编译时标记数字?

[英]Are compile-time tagged numbers possible in TypeScript?

举个例子,我想创建一个Port类型和一个Seconds类型,这两个类型都是围绕number类型的薄包装,这样两者都不能分配给另一个。

let httpPort: Port = 80;
let oneMinute: Seconds = 60;

httpPort = oneMinute; // type error
oneMinute = httpPort; // type error

我们可以通过unique symbol获得一些类型安全的外观。 具体来说,声明类型unique symbol的字段永远不会与同名的另一个字段比较兼容,除非它来自相同的声明。 所以我们可以用虚假的独特符号标记我们的数字,使它们无与伦比。

type Port = number & { readonly __tag: unique symbol };
type Seconds = number & { readonly __tag: unique symbol };

// Note that we do have to explicitly cast the numbers, as we're
// technically lying to the type system to get this behavior.
let httpPort = 80 as Port;
let oneMinute = 60 as Seconds;

现在httpPortoneMinute是互不兼容的。 如果我们尝试比较它们,我们会得到这样的结果。

file.ts:8:1 - error TS2322: Type 'Seconds' is not assignable to type 'Port'.
  Type 'Seconds' is not assignable to type '{ readonly __tag: unique symbol; }'.
    Types of property '__tag' are incompatible.
      Type 'typeof __tag' is not assignable to type 'typeof __tag'. Two different types with this name exist, but they are unrelated.

8 httpPort = oneMinute; // type error

不幸的是,我们仍然可以做一些无意义的事情,比如将两个端口或一个端口或一个第二个添加在一起,因为 Typescript 会很高兴地将它们中的任何一个向上转换为number (毕竟交集类型就是这样工作的),但至少我们不能通过一个Port到一个需要Seconds的函数,或者错误地分配变量。

请注意,您尝试执行的操作通常被称为“newtype 模式”,位于 Haskell 中的newtype关键字之后(正是为此目的而存在的)。 特别是,您可以在此页面上阅读有关它在 Typescript 中使用的更多信息(我也是在这里学到了这个小技巧)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM