我可以在TypeScript中声明自定义数字类型吗?

7
我能否声明自定义数字类型?例如我想要一个UnixMsDate和一个UnixSDate类型,并且希望TS可以帮助我始终区分和消除这两者之间的歧义,以便我永远不会意外混淆它们。同时我也希望能够明确地在它们之间(以及数字之间)进行转换。
我尝试过`type UnixMsDate = number`,并且它编译通过,但它似乎只是一个可交换的数字别名。
请问我是否有可能实现我的需求?

看一下这个 GitHub 提案。这是一个非常棘手的问题,但是对于这个主题还有持续的思考和讨论。 - Aluan Haddad
1个回答

9

使用枚举

enum UnixMsDate { }
enum UnixSDate { }

let date1: UnixMsDate;
let date2: UnixSDate;

date1 = date2; // Type 'UnixSDate' is not assignable to type 'UnixMsDate'.

function foo(x: UnixMsDate) { }
foo(date2); // Argument of type 'UnixSDate' is not assignable to type 'UnixMsDate'.

// All the below work.
date1 = +new Date();
date1 += 22;
console.log(date1 + date2);
date1 = 3.14159;
x1 = +x2;
x1 = Number(x2);
foo(+x2);

使用交叉类型的替代方法

您可以使用交叉类型来实现相同的功能:

type A = number & { _A: void; };
type B = number & { _B: void; };

这个操作和之前的几乎一样,唯一需要注意的是在赋值时需要进行类型转换:

let a: A = <A>222;

它仍然无法阻止将两种类型的数字相加。这个链接提供了更多关于这种方法的信息。

嗯,这已经接近我想要的了,谢谢!我真的很喜欢它能捕捉并禁止隐式的 date1 = date2foo(date2)。但是,我担心它仍然允许 date1 + date2。我是否可以以某种方式使类型检查器也禁止这种情况?理想情况下,它仍然应该允许 date1 + date1,但如果不行也不是大问题。 - Wizek
1
我已经没有精力了。如果有什么方法可以做你想要的事情,我肯定不知道是什么。当然,你可以将这两种类型转换为包含原始值的类。 - user663031

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接