typescript - 为什么 Typescript 接口(interface)允许自引用?

标签 typescript types

type SomeGeneric<T> = {
    x: T;
}

type TTest = SomeGeneric<TTest> & { a: string; }; // Type alias 'TTest' circularly references itself.

interface ITest extends SomeGeneric<ITest> { // OK
    a: string;
}

我不明白为什么允许接口(interface)在它们自己的声明中引用它们自己而类型却不允许。

最佳答案

类型别名不能递归(大多数情况下),而接口(interface)可以。如果您搜索 GitHub,可以找到几个关于原因的答案。

例如 RyanCavanaugh 解释 here :

Type aliases and interfaces are subtly different and there are rules about self-recursion for aliases that don't apply to interfaces. Because an alias is supposed to always be "immediately expandable" (it's as if it were an in-place expansion of its referand), there are things you can do interfaces you can't do with type aliases.

here作者:丹尼尔罗森瓦瑟

The restriction that a type alias can't be referenced by itself at the top level has been the behavior since we implemented type aliases; however, you might recall that a while back, we started allowing type aliases to be referenced from within an object type. ... However, it has no problem provided that the type can be expanded, or "unrolled" one level at a time. In other words, as long as you have some sort of box-y thing containing the type:

如果您需要递归类型,一般的解决方法是使用接口(interface)。

请注意,这些规则并没有完全一致地执行。例如,在您的情况下 SomeGeneric<TTest>可以扩展为 { x: TTest }编译器甚至不尝试它,它只是失败了。然而,以下递归定义将起作用:

type TTest = { x: TTest } & { a: string; };

关于typescript - 为什么 Typescript 接口(interface)允许自引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53279304/

相关文章:

node.js - 使用 TypeORM 在 Postgres bytea 上保存缓冲区仅存储 10 个字节

typescript - 如何在 typescript 中创建和导入自制环境模块?

haskell - 为什么在 monad 中使用如此奇特的函数类型?

java - 'messy'字符串到int转换java

java - 如何将具有泛型的类型转换为java中的类?

Java 泛型不兼容类型

javascript - 否定后视不匹配转义字符,在转义反斜杠上失败

javascript - Angular 的循环模板可以通过枚举循环吗?

javascript - ReactJS es-lint : Return statement should not contain assignment

java - 安全转换 <?将 Response> 扩展到 <Response>