泛型类型(T)与打字稿中的任何类型有什么区别

Ram*_*ran 32 javascript generics types typescript angular

打字稿中的generic Type(T)vs有什么区别any

功能1

function identity(arg: any): any {
    return arg;
}
Run Code Online (Sandbox Code Playgroud)

功能2

function identity<T>(arg: T): T {
    return arg;
}
Run Code Online (Sandbox Code Playgroud)

功能3

function identity<T>(arg: T[]): T[] {
    return arg;
}
Run Code Online (Sandbox Code Playgroud)

如果我们传递任何类型的函数1和3被接受data type,但是如果我们通过函数2则不接受array.泛型类型在编译时接受所有类型的数据类型.但这里为什么不接受?

哪个功能有利于提高性能(功能1或功能3)?

Est*_*ask 24

如果这是只返回一个参数并且在没有类型限制的情况下使用的标识函数,则没有区别:

const foo: any = fn(['whatever']);
Run Code Online (Sandbox Code Playgroud)

输入代码有所不同:

const foo: string = fn('ok');
const bar: string = fn([{ not: 'ok' }]);
Run Code Online (Sandbox Code Playgroud)

此外,泛型类型的使用提供了语义.此签名表明该函数是无类型的并返回任何内容:

function fn(arg: any): any { ... }
Run Code Online (Sandbox Code Playgroud)

此签名表明该函数返回与其参数相同的类型:

function fn<T>(arg: T): T { ... }
Run Code Online (Sandbox Code Playgroud)

实际函数通常比return arg示例更有意义.通用类型可以受益于类型限制(但any显然不能):

function fn<T>(arg: T[]): T[] {
  return arg.map((v, i) => arg[i - 1]);
}
Run Code Online (Sandbox Code Playgroud)

但是当函数与其他泛型类和泛型函数一起使用时,这些好处变得更加明显(如果涉及非泛型函数,则会消除):

function fn<T>(arg: T[]): T[] {
  return Array.from(new Set<T>(arg));
}
Run Code Online (Sandbox Code Playgroud)

这允许T在输入(参数)和输出(返回值)之间始终保持类型:

const foo: string[] = fn(['ok']);
const bar: string[] = fn([{ not: 'ok' }]);
Run Code Online (Sandbox Code Playgroud)

性能没有任何差异,因为TypeScript类型仅在设计时存在.


Mil*_*lad 16

使用任何这些方法时绝对没有性能差异,因为所有这些奇特的东西都只是Typescript糖而且仅用于开发.

所有类型检查仅在编译时(当Typescript将您的代码转换/转换回正常的javascript,在您的服务器中).

无论哪种方式,当您的代码发送到用户的浏览器时,它的外观如下:

function identity(arg){
    return arg;
}
Run Code Online (Sandbox Code Playgroud)

但要解释这些差异:

使用时,any你将失去所有类型检查和Typescript提供的安全检查,而T行为就像一个变量,它将保存你不知道它将是什么的类型.

所以

function identity<T>(arg: T): T {
    return arg;
}
Run Code Online (Sandbox Code Playgroud)

在上面,我们知道如果identify接受number,它将返回number等等,其中:


function identity(arg: any): any {
    return arg;
}
Run Code Online (Sandbox Code Playgroud)

但现在,您不知道是否argreturned值是相同的类型.


另一个T要解决的问题是当你在一个类中创建一个方法时,它期望一个参数,你要确保这个方法在实例化时只接受具有相同类型的类的构造函数参数的参数.

export class MyClass<T>{

   myMethod(anotherArg:T){}

}
Run Code Online (Sandbox Code Playgroud)

所以使用上面:

let str = "string";
let instance = new MyClass(str);
instance.myMethod("other string") // will compile
Run Code Online (Sandbox Code Playgroud)

在哪里:

let num = 32423423;
let instance = new MyClass(num);
instance.myMethod("other string") // won't compile
Run Code Online (Sandbox Code Playgroud)