答案 0 :(得分:1)
在运行时不会有区别,但在编译时你可以使用一个叫做 branding 的技巧让编译器认为 UserId
扩展 number
:
type UserId = number & { __userId: true };
通过带有对象类型的 intersecting number
,我们定义了一个扩展 number
但没有扩展的类型 number
。请注意
const someUser = new User(1 as UserId);
使用 type assertion 欺骗编译器;根据该定义,1
并不是真正的 UserId
。并且这种谎言是必要的,因为您真的不想尝试在运行时将 __userId
属性添加到原始 number
(您可能会弄乱 Number
原型,但这会增加每个 number
都有这样的属性,这违背了目的)。
但它可以满足您的需求:
usersIds.push(someUser.id); // okay
usersIds.push(2); // error!
// Argument of type 'number' is not assignable to parameter of type 'UserId'