import { A } from "https://example.com/type.d.ts";
type B = A | A
如果您在TS Playground和VS Code中都将鼠标悬停在B
上,它将在shell type B = A
中显示为A
,在shell type B = A | A
中显示为any
.不管A是否已知,我希望它们应该是一致的.为什么不是这样呢?
import { A } from "https://example.com/type.d.ts";
type B = A | A
如果您在TS Playground和VS Code中都将鼠标悬停在B
上,它将在shell type B = A
中显示为A
,在shell type B = A | A
中显示为any
.不管A是否已知,我希望它们应该是一致的.为什么不是这样呢?
根据microsoft/TypeScript#54630,特别是this comment by the TS team dev lead:
对于当程序中存在错误类型时会发生什么,没有具体的保证.
当你导入一些找不到的东西时,你会得到一个编译器错误:
import { A } from "https://example.com/type.d.ts"; // error!
// -------------> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Cannot find module 'https://example.com/type.d.ts' or its corresponding type declarations.
任何对它的引用都将显示为TypeScript想要显示的任何形式. 它通常会显示为the any
type,because
悬停显示"任何",因为缺少更好的显示.它可以被区分,但这些东西往往不会在程序中停留很长时间.
这就是为什么你看到any
sometimes.
至于为什么它显示A
而不是any
时,你从
type B = A | A
// ^? type B = any
到
type C = A;
// ^? type C = A
there's no documented and stable rule by which such types are displayed. Assuming that A
is sometimes displayed as any
, then it's really the compiler's prerogative 到 decide which one of those it wants 到 display. Even if A
weren't an error, you'd still have such a dicho到my:
type D = { a: string };
type E = D;
// ^? type E = { a: string; }
type F = D[];
// ^? type F = D[];
There you have type D
, which is clearly an alias for {a: string}
. Some uses of D
get reduced 到 {a: string}
, while others stay as D
.
These differences are only how the type gets displayed 到 the user, and shouldn't affect the actual identities of the types. There are no supported official mechanism by which a developer can just tell the compiler which form she would prefer 到 see when displaying a type. There are various open feature requests like microsoft/TypeScript#28508, microsoft/TypeScript#31940, and microsoft/TypeScript#45954, which could possibly change that if they were implemented, but for now it's not part of the language. The compiler uses heuristics 到 determine which is the type 到 display; these heuristics perform well enough in a wide range of use cases, but it is necessarily the case that they cannot meet everyone's needs simultaneously. For every person who wants D
到 be displayed as {a: string}
, there is an equal and opposite person who wants it do be displayed as D
, and they both have very important reasons for it 到 be that way, and both think their way would make things "consistent". More developer control would be nice, but without that, you just get what you get.
So: I can't easily say for certain why you see any
for A | A
but A
for A
, without stepping through the TypeScript compiler code and maybe finding pull requests that document the parts responsible. But even if I did that, it wouldn't be particularly enlightening, and it could easily change in a future version of TypeScript. As long as two types are identical, in some sense it's completely up 到 the compiler 到 decide which one 到 show and when.