如何理解类型 any、unknown、{} 之间以及它们与其他类型之间的关系? [英] How to undestand relations between types any, unknown, {} and between them and other types?

查看:24
本文介绍了如何理解类型 any、unknown、{} 之间以及它们与其他类型之间的关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图理解类型之间的关系我有这个代码

Trying to understand relations between types I have this code

type CheckIfExtends<A, B> = A extends B ? true : false;

type T1 = CheckIfExtends<number, unknown>; //true
type T2 = CheckIfExtends<number, {}>; //true
type T3 = CheckIfExtends<number, any>; //true
type T4 = CheckIfExtends<() => void, unknown>; //true
type T5 = CheckIfExtends<() => void, {}>; //true
type T6 = CheckIfExtends<() => void, any>; //true
type T7 = CheckIfExtends<unknown, any>; //true
type T8 = CheckIfExtends<any, unknown>; //true
type T9 = CheckIfExtends<{}, unknown>; //true
type T10 = CheckIfExtends<{}, any>; //true
type T11 = CheckIfExtends<any, {}>; //boolean
type T12 = CheckIfExtends<unknown, {}>; //false

链接到游乐场

有人能解释一下吗?有什么区别?any extends {}any 怎么可能不会同时扩展 {}?如果 any extends unknownunknown extends any 那么这是否意味着它们是强相等的?难道是 Typescript 在 JavaScript 的 nullundefinded 权益问题之上的新缺陷?

Could someone explain this? What difference? How is it possible that any extends {} and any does not extend {} at the same time? If any extends unknown and unknown extends any then does it mean they are strongly equal? Is it a new flaw of Typescript on top of null and undefinded equity issue of JavaScript?

其实

type T = CheckIfExtends<any, number>; //boolean

推荐答案

本质上的区别在于:

  • any 类型 故意不合理,因为它可以分配给和来自任何其他类型(never 可能除外,这取决于您使用它的位置).不健全意味着类型的一些基本规则被破坏,例如传递性://en.wikipedia.org/wiki/Subtyping" rel="noreferrer">子类型.一般来说,如果A可以赋值给B,而B可以赋值给C,那么A 可分配给 C.但是 any 打破了这一点.例如:string 可分配给 anyany 可分配给 number... 但 字符串 不能分配给number.这种特殊的不健全非常有用,因为它允许我们从根本上关闭"难以或不可能正确键入的代码部分中的类型检查.但是您需要非常小心地将 any 视为一种类型;它更像是一种非类型".

  • the any type is deliberately unsound, in that it is assignable both to and from any other type (with the possible exception of never, depending on where you're using it). Unsoundness means that some basic rules for types are broken, such as transitivity of subtyping. Generally, if A is assignable to B, and B is assignable to C, then A is assignable to C. But any breaks this. For example: string is assignable to any, and any is assignable to number... but string is not assignable to number. This particular unsoundness is very useful, because it allows us to essentially "turn off" type checking in a part of code which is either hard or impossible to type correctly. But you need to be very careful thinking of any as a type; it's more of an "un-type".

空类型,{} 是一种可以在运行时被视为对象的类型(也就是说,您可以从中读取属性或方法而不会出现运行时错误),但它具有编译时没有已知属性.这并不意味着它没有属性;它只是意味着编译器不知道它们中的任何一个.这意味着只有 nullundefined 不能分配给 {}(null.fooundefined.foo 是运行时错误).甚至像 string 这样的原始类型也可以在运行时被视为具有属性和方法("".length"".toUpperCase() 工作,甚至 "".foo 只返回 undefined).当然,任何实际对象类型也将分配给 {}.

the empty type, {}, is a type that can be treated like an object at runtime (that is, something you can read properties or methods from without a runtime error), but it has no known properties at compile time. That doesn't mean it has no properties; it just means that the compiler doesn't know about any of them. This implies that only null and undefined are not assignable to {} (null.foo or undefined.foo are runtime errors). Even primitive types like string can be treated as having properties and methods at runtime ("".length and "".toUpperCase() work, and even "".foo just returns undefined). And of course any actual object type will also be assignale to {}.

另一方面,{} 类型不能分配给很多类型.如果我尝试将 {} 类型的值分配给 {foo: string} 类型的变量,则会出现编译器错误,如 {} 不知道包含 foo 属性.您可以将 {} 分配给自身,或分配给更广泛的类型(如 unknown),或分配给un-type"any.

On the other hand, the {} type is not assignable to very many types. If I have value of type {} as try to assign it to a variable of type {foo: string}, there will be a compiler error, as {} is not known to contain a foo property. You can assign {} to itself, or to a wider type like unknown, or to the "un-type" any.

这使得 {} 非常几乎 成为顶级type,这是所有其他类型都可以分配的类型.它本质上是一个顶部类型,其中删除了 nullundefined.

This makes {} very nearly a top type, which is a type to which all other types are assignable. It's essentially a top type with null and undefined removed from it.

unknown 类型是在 TypeScript 3.0 中引入的,是 true 顶级类型;TypeScript 中的每个类型都可以分配给 unknown.甚至 nullundefined 也可以分配给 unknown.

the unknown type was introduced in TypeScript 3.0 and is the true top type; every type in TypeScript is assignable to unknown. Even null and undefined are assignable to unknown.

另一方面,unknown 只能分配给它自己和un-type"any.即使 {} 类型也不够宽,您无法将 unknown 分配给它.从概念上讲,您应该能够将 unknown 分配给联合类型 {} |空|未定义,但这是故意未实施以保持unknown 作为真正的"顶级类型.

Again, on the other hand, unknown is only assignable to itself and the "un-type" any. Even the {} type isn't wide enough for you to assign unknown to it. Conceptually you should be able to assign unknown to the union type {} | null | undefined, but this is intentionally not implemented to keep unknown as the "true" top type.

您的大部分 CheckIfExtends 结果都可以通过上述解释.例外是T11:

Most of your CheckIfExtends<A, B> results can be explained by the above. The exception is T11:

type T11 = CheckIfExtends<any, {}>; //boolean

您的 CheckIfExtends 类型定义是 分布式条件类型,当 A 是联合类型时,它会做一些有趣的事情,因为它允许条件的两个分支如果联合的部分满足两个分支,则采用.当 Aany 时,它也做同样的分布,除非 Banyunknown (所以 T8 表现正常).microsoft/TypeScript#27418 对此有一些讨论.无论如何,T11 需要两个分支,你就会得到 true |falseboolean.(来自 microsoft/TypeScript#27418,A 位置的 unknown 不分布,所以 T7T12 表现通常也是如此).

Your CheckIfExtends<A, B> type definition is a distributive conditional type, which does some interesting things when A is a union type, in that it allows both branches of the conditional to be taken if the pieces of the union satisfy both branches. It also does the same distribution when A is any, except when B is any or unknown (so T8 behaves normaly). There's some discussion of this in microsoft/TypeScript#27418. Anyway, T11 takes both branches and you get true | false which is boolean. (From microsoft/TypeScript#27418, unknown in the A position does not distribute, so T7 and T12 behave normally as well).

好的,希望有帮助;祝你好运!

Okay, hope that helps; good luck!

这篇关于如何理解类型 any、unknown、{} 之间以及它们与其他类型之间的关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆