打字稿类型别名允许智能感知显示别名,而不是源类型



考虑这段简短的代码

type A = number;
declare function f(): A;
const a = f(); // `a` is number, not A

为什么 TS 显示a: number而不是a: A

名称所暗示的类型别名只是另一种类型的不同名称。类型别名不是编译器保证保留的内容(与接口不同(,它应用了提供最佳用户体验的启发式方法(在这种情况下,它可以失败(。

也不是说Anumber实际上是同一类型。如果要确保number不可分配A则需要使用品牌类型。

type A = number & { isA: undefined};
declare function f(): A;
const a = f(); // `a` is A, not number

注意:还有一个建议(这个和这个(将品牌类型机制烘焙到打字稿中,但在撰写本文时尚未最终确定。

下面介绍了如何保留别名,同时将其用作数字

interface PreserveAliasName extends Number {}
type A = number & PreserveAliasName;
declare function f(): A;
const a = f(); // `a` is A
const b: A = 5; // allows primitive assign, unlike branded types
const c = BigInt(b); // still allows usage like primitive
<小时 />

与品牌类型相比:

type A = number & { __brand: 'A' };
declare function f(): A;
const a = f(); // `a` is A
const b: A = 5;
Type 'number' is not assignable to type '{ __brand: "A"; }'
const b: A = 5 as A; // needs casting
const c = BigInt(b); // still allows usage like primitive

与界面相比

interface A extends Number {}
declare function f(): A;
const a = f(); // `a` is A
const b: A = 5; // allows primitive assign
const c = BigInt(b)
Argument of type 'A' is not assignable to parameter of type 'string | number | bigint | boolean'.
const c = BigInt(b as number) // needs casting

最新更新