如何在TypeScript中定义不透明类型? class Foo; interface Foo {};

如何在TypeScript中定义不透明类型? class Foo; interface Foo {};,typescript,Typescript,。。。并将其用作句柄,例如在声明函数签名时 void printFoo(const Foo& foo); 然后,应用程序代码可能使用对Foo的引用或指向Foo的指针,而看不到Foo的实际定义 TypeScript中有类似的东西吗?如何定义不透明类型 我的问题是如果我定义这个 class Foo; interface Foo {}; 。。。然后,它可以自由地与其他类似类型互换。有一个成语吗?这是因为TypeScript类型系统是“结构化的”,所以任何两个具有相同形状的类型都可以相互分

。。。并将其用作句柄,例如在声明函数签名时

void printFoo(const Foo& foo);
然后,应用程序代码可能使用对Foo的引用或指向Foo的指针,而看不到Foo的实际定义

TypeScript中有类似的东西吗?如何定义不透明类型

我的问题是如果我定义这个

class Foo;
interface Foo {};

。。。然后,它可以自由地与其他类似类型互换。有一个成语吗?

这是因为TypeScript类型系统是“结构化的”,所以任何两个具有相同形状的类型都可以相互分配一个-与“名词性”相反,在这里引入一个新名称,如
Foo
,将使其不可分配给相同的形状
Bar
类型,反之亦然

在TS中添加了跟踪标称打字的功能

TS中不透明类型的一种常见近似方法是使用唯一标记使任意两种类型在结构上不同:

// opaque type module:
export type EUR = { readonly _tag: 'EUR' };
export function eur(value: number): EUR {
  return value as any;
}
export function addEuros(a: EUR, b: EUR): EUR {
  return ((a as any) + (b as any)) as any;
}

// usage from other modules:
const result: EUR = addEuros(eur(1), eur(10)); // OK
const c = eur(1) + eur(10) // Error: Operator '+' cannot be applied to types 'EUR' and 'EUR'.
更好的是,可以使用唯一的符号对标签进行编码,以确保它永远不会被访问或以其他方式使用:

declare const tag: unique symbol;
export type EUR = { readonly [tag]: 'EUR' };
请注意,这些表示在运行时没有任何影响,唯一的开销是调用
eur
构造函数

提供通用实用程序,用于定义和使用行为类似于上面示例的类型的值

品牌类型

另一个典型用例是仅在一个方向上保持不可分配性,即处理可分配给
编号的
EUR
类型:

declare const a: EUR;
const b: number = a; // OK
这可以通过所谓的“品牌类型”获得:


例如,请参见此

是否查看泛型类型?我不确定是否真的理解你的问题,但这可能会对你有所帮助。我认为你正在寻找品牌类型:@TitianCernicova Dragomir是的,就是这样。您想回答这个问题还是我将其删除?@ChrisW我认为其他品牌类型的问题都没有提及不透明,因此添加一个答案以提高搜索能力可能是有用的。。。我会在会议结束后再加上一个,可能会重复看到这个很棒的