繁体   English   中英

TypeScript中泛型的行为

[英]Behavior of Generics in the TypeScript

我想稍微学习一下TS,并且正在关注官方页面

我在泛型章节

从指南:

function identity(arg: any): any {
    return arg;
}

他们声明如下:

虽然使用any肯定是通用的,因为它将导致函数接受arg类型的任何类型和所有类型,但实际上,我们丢失了有关函数返回时该类型的信息 如果我们传入一个数字,则唯一的信息就是可以返回任何类型。

现在让我们观察这段代码:

let whatIsMyType = identity(666);
typeof whatIsMyType; // number

我没有丢失类型信息。 他们指的是哪种损失?

进一步阅读,指南建议使用T型,如:

function identity<T>(arg: T): T {
    return arg;
}

附带说明:

现在,我们向身份函数添加了类型变量T。 此T允许我们捕获用户提供的类型(例如,数字),以便我们以后可以使用该信息。 在这里,我们再次使用T作为返回类型。 通过检查,我们现在可以看到参数和返回类型使用相同的类型。 这使我们能够将键入信息的信息投放到函数的一侧,而另一端则从其中流出。

最后:TS中的功能(具有任何类型的签名)

function identity(arg: any): any {
    return arg;
}

以及具有通用类型T的函数:

function identity<T>(arg: T): T {
return arg;

}

一旦编译为普通的JS,它们看起来都是相同的:

function identity(arg) {
    return arg;
}

现在,我了解了预警的好处,也了解了任何签名。 我不明白为什么说我丢失了类型,我应该使用“ T”签名代替。

这更复杂,并且基本上是相同的。

现在让我们观察这段代码:let whatIsMyType = identity(666); whatIsMyType的类型; //数字我还没有丢失类型信息。 他们指的是哪种损失?

它涉及静态类型信息和运行时类型信息之间的差异。 TypeScript都是关于静态类型信息的,TypeType编译器可以使用该信息来帮助您保持程序代码正确。 但是typeof (在这种情况下)是一种运行时操作,它告诉您在变量上使用typeof时在运行时变量whatIsMyType中存储了哪种值。

如果将代码粘贴到操场上,然后将鼠标悬停在whatIsMyType变量上,则会看到它的类型为any ,这意味着您可以在对identity的调用之后为它高兴地分配"foo"

function identity(arg: any): any {
    return arg;
}
let whatIsMyType = identity(666);
console.log(whatIsMyType);
whatIsMyType = "foo";          // No error here
console.log(whatIsMyType);

出于所有目的和目的,变量的类型类似于JavaScript变量。

TypeScript的目标是存在静态类型检查。 对于静态类型检查无用(或由于第三方集成而可能实现)的那些情况(确实存在,但很少见), any都有效。

一旦编译为普通的JS,它们看起来都是相同的:

那就对了。 TypeScript使用的静态类型信息不是最终输出的一部分。 这是编译时的事情,而不是运行时的事情。 但是请注意使用泛型是如何改变的—如果您在操场上运行以下代码:

function identity<T>(arg: T): T {
    return arg;
}
let whatIsMyType = identity(666);
console.log(whatIsMyType);
whatIsMyType = "foo";       // <== Error: Type '"foo"' is not assignable to type 'number'.
console.log(whatIsMyType);

...您可以看到,将whatIsMyType "foo"现在是编译时错误。


¹ “ .. typeof (在这种情况下...)...”有点令人困惑,您可以在TypeScript中使用静态的typeof关键字,该关键字可以在需要输入类型的地方使用,这与JavaScript的运行时typeof关键字(在您的示例中使用)不同。 在TypeScript中,在变量声明中的某些位置,例如,在:之后有一个类型类型上下文 ):

let a: type_expected_here;

...以及其他需要值的地方( 值上下文 ),例如赋值的右侧:

a = value_expected_here;

如果在类型上下文中使用typeof ,则它是TypeScript的typeof运算符。 例如,如果您有以下声明:

let foo: number = 42;

...您可以使用typeof bar声明一个类型与foo相同的变量, 如下所示

let a: typeof foo;

由于使用typeof是期望的类型 ,因此a将具有类型number因为那是foo的类型。 如果你改变foo的声明,所以这是一个字符串,而不是, a的类型将改变跟风。

相反:

let a = typeof foo;

那里, typeof值上下文中 ,因此它是JavaScript的运行时typeof关键字,并且a将获得值(而非类型) "number" (在该特定示例中, a 's的类型推断为string ,因为这就是JavaScript的含义) typeof的结果始终是)。

乍一看似乎很令人困惑,但随着时间的推移会变得更加清晰。

可悲的是,文档中没有很好地描述TypeScript的typeof :-|


请注意,以上所有内容都是从TypeScript角度来看的。 是否找到静态类型检查帮助或障碍取决于您。 :-)但是出于这个答案的目的,我假设使用TypeScript透视图。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM