是否可以在TypeScript中定义一个不会自动推断为别名的类型?
type id = string;
type int = number;
如果没有明确指定为声明的类型,那么我想得到一个错误:
function foo(id: id) {}
var s:string = "123";
foo(s); // error?
我希望foo("123")
也是一个错误,除非你投了它:foo("123" as id)
答案 0 :(得分:1)
认为这是不可能的,因为TS使用结构而非名义输入。您可以在此处找到更多信息:
https://www.typescriptlang.org/docs/handbook/type-compatibility.html
猜猜你是否需要这个功能,你必须切换到flow-type。他们得到了这个:https://flow.org/en/docs/types/opaque-types/
编辑:猜猜这是TS团队的计划:Microsoft/TypeScript#5228
答案 1 :(得分:1)
在TypeScript中获取此行为的主要方法是一种名为"branding"的技术(另请参阅Microsoft/Typescript#4895中的讨论)。我们的想法是,您使用没有运行时效果的“品牌”来扩充基本类型,但这会使类型系统将其与基本类型区分开来。
对于您的情况,我们可以这样做:
type id = string & { __brand: 'id' };
type int = number & { __brand: 'int' };
function foo(id: id) {}
var s:string = "123";
foo(s); // error
foo("123"); // error
foo("123" as id) //okay
正如您所看到的,它的行为或多或少完全符合您的要求。请注意,它仍然认为品牌类型与基本类型兼容,因此您可以这样做:
const i: int = 5 as int;
const j: number = i; // that's okay, an int is a number
这种技术的主要缺点是你基本上对类型系统说谎:__brand
或string
没有number
属性。但如果品牌是good enough for the compiler itself,那对我们来说可能已经足够了。
还有其他方法可以进行品牌/标记,但这应该适合您。祝你好运!