Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 如何理解any、unknown、{}类型之间以及它们与其他类型之间的关系?_Typescript_Types - Fatal编程技术网

Typescript 如何理解any、unknown、{}类型之间以及它们与其他类型之间的关系?

Typescript 如何理解any、unknown、{}类型之间以及它们与其他类型之间的关系?,typescript,types,Typescript,Types,试图理解类型之间的关系我有这个代码 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 =

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

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

我将从TypeScript中的
扩展
的含义开始。乍一看,它的行为很奇怪,对于产品类型(如对象)来说,它的行为类似于“is超集”,对于
unions
as“is子集”,它的工作方式也完全不同于函数类型。一开始它可能看起来很奇怪,但它是逻辑行为,换句话说,大多数类型都有

我理解这个概念的经验法则是将
扩展为
可分配给
。然后,如果
x
扩展
y
,则意味着只要需要
y
,就可以使用
x

让我们考虑三种不同的代数数据类型,如果它们是正确的。< /P> 用于产品类型

type A = {a: string}
type B = {a: string; b: number}
type BextendsA = B extends A ? true : false // evaluates to true 
type A = number | string
type B = number
type BextendsA = B extends A ? true : false // evaluates to true 
以上是正确的,因为B可以在需要A的每个地方使用,因为B覆盖了A的整个结构。B是a的超集,但这里所包含的是B可以赋值给a

用于活接头类型

type A = {a: string}
type B = {a: string; b: number}
type BextendsA = B extends A ? true : false // evaluates to true 
type A = number | string
type B = number
type BextendsA = B extends A ? true : false // evaluates to true 
完全不同的是,它寻求联盟。对于产品B是一个超集,对于联合体B是一个子集!是的,不同的逻辑,B并不代表A中所有可能的值,但只要需要A,B就可以使用。所以B可以分配给A

对于功能类型

type A = (a: number) => void
type B = () => void
type BextendsA = B extends A ? true : false // evaluates to true 
对于函数类型,它看起来更奇怪,因为A看起来比B更像指定的函数,那么B如何扩展A呢?这又是从可分配性开始的,因为无论什么时候需要A,我们都可以分配B。这在像
Array.map
这样的示例中非常明显。考虑:

[1,2].map(x => x + 1)
Array.map需要有三个参数的函数-
(el,index,arr)=>any
,但可以使用只有一个参数的函数
el=>any
。它同样具有可转让性,B可转让给A


any
unknown
{}
这样的类型是不可靠的,这意味着它们的行为无法在逻辑上得到证明。理解他们在TS中的行为更像是理解这些决策的规范和原因。但它不能从逻辑上解释,因为不健全的类型违背逻辑

我们仔细考虑了TypeScript允许不健全行为的地方,在本文档中,我们将解释这些情况发生的地方以及背后的激励场景


区别主要在于:

  • 是故意不合理的,因为它既可分配给任何其他类型,也可从中分配给任何其他类型(可能的例外是
    从不
    ,这取决于您使用它的位置)。不健全意味着类型的一些基本规则被破坏,例如of。通常,如果
    A
    可分配给
    B
    ,而
    B
    可分配给
    C
    ,则
    A
    可分配给
    C
    。但是
    any
    打破了这一点。例如:
    字符串
    可分配给
    任何
    ,而
    任何
    可分配给
    数字
    。。。但是
    字符串
    不能分配给
    数字
    。这种特殊的不健全是非常有用的,因为它允许我们从本质上“关闭”代码中很难或不可能正确键入的部分的类型检查。但是你需要非常小心地把
    任何
    看作一种类型;这更像是一种“联合国类型”

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

    另一方面,
    {}
    类型不能分配给很多类型。如果我将类型为
    {}
    的值分配给类型为
    {foo:string}
    的变量,则会出现编译器错误,因为
    {}
    不包含
    foo
    属性。您可以将
    {}
    分配给自身,或分配给更广泛的类型,如
    未知
    ,或分配给“untype”
    任意

    这使得
    {}
    非常接近,这是一种所有其他类型都可分配的类型。它本质上是一个top类型,从中删除了
    null
    undefined

  • 是在TypeScript 3.0中引入的,是真正的顶级类型;TypeScript中的每种类型都可分配给
    未知
    。甚至
    null
    undefined
    也可分配给
    unknown

    另一方面,
    unknown
    仅可分配给自身和“untype”
    any
    。即使是
    {}
    类型也不够宽,您无法将
    unknown
    分配给它。从概念上讲,您应该能够将
    unknown
    分配给联合类型
    {}null | undefined
    ,但这是为了将
    unknown
    保留为“true”顶部类型


A
是一个并集类型时,大部分的
CheckIfExtends都会做一些有趣的事情,因为如果并集的片段满足两个分支,那么它允许使用条件的两个分支。当
A
any
时,其分布也相同,但
B
any
未知
时除外(因此
T8
表现正常)。有一些问题