vas*_*sia 3 types casting typescript typescript-typings
假设我有两个或多个类型别名,例如:
declare type A = string;
declare type B = string;
我有这些类型的变量,以及对它们进行操作的函数。
const a1: A = "example of a";
const b1: B = "example of b";
function withA(a: A){
    console.log(a);
}
function withB(b: B){
    console.log(b);
}
我希望以下代码出错,但不会:
withA(b1);
withB(a1);
我怎样才能做到这一点?我还需要能够用字符串初始化变量(我假设是强制转换)。但是,一旦初始化,我不希望这些类型“隐式等效”,并且希望编译器禁止它们的互换使用。
我也不想使用类,如下所述: TypeScript - specific string types
顾名思义,类型别名不会向它们别名的类型添加任何内容。所以就TS而言都A和B属于同一类型,即string。
您可以做的是使用品牌类型。这是一种采用基本类型(string在这种情况下)并将其与具有属性的对象类型相交的技术,以便从编译器的角度来看,使该类型在结构上与任何其他类型不兼容。该属性不需要在运行时存在,它只是作为编译器的标记存在:
type A = string & { __brand: "A"};
type B = string & { __brand: "B"};
const a1: A = makeA("example of a");
const b1: B =  makeB("example of b");
function makeA(s: string) {
    return s as A
}
function makeB(s: string) {
    return s as B
}
function withA(a: A){
    console.log(a);
}
function withB(b: B){
    console.log(b);
}
withA(b1); // error
withB(a1); // error
效用函数makeA和makeB是不是绝对必要的,你可以只使用一种类型的断言,当你分配string,但是他们做出更好的DX。
注意:有两种在类型系统(结构tag type品牌和名义unique type品牌)中形式化这种技术的建议,但在撰写本文时都没有合并,也许在未来的 TS 版本中我们会得到其中一个。