软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,

这在创建大型系统时为你提供了十分灵活的功能。

In software engineering, we should not only create well-defined APIs, but also consider reusability. Components can support not only

current data types, but also future data types.This provides you with very flexible functionality when creating large systems.

在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

In languages like C# and Java, generics can be used to create reusable components, and a component can support multiple types of data.

This allows users to use components with their own data types.

泛型之Generic

Generic Generic

identity函数。 这个函数会返回任何传入它的值。 你可以把这个函数当成是echo命令。

identity Function. This function returns any value passed in. You can think of this function as echo command.

不用泛型的话,这个函数可能是下面这样:

Without generics, this function might be as follows:
function identity(arg:number):number{
return arg;
}
function identity(arg:any):any{
return arg;//传入的类型与返回的类型应该是相同的。
}

我们需要一种方法使返回值的类型与传入参数的类型是相同的。 这里,我们使用了 类型变量,它是一种特殊的变量,只用于表示类型而不是值。

We need a way to make the type of the return value the same as the type of the incoming parameter. Here, we use a type variable,

which is a special variable and is used only to represent a type rather than a value.

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

我们定义了泛型函数后,可以用两种方法使用。 第一种是,传入所有的参数,包含类型参数:

After we define generic functions, we can use them in two ways. The first is to pass in all parameters, including type parameters:

let output=identity<string>("myString");//string

第二种方法更普遍。利用了类型推论 -- 即编译器会根据传入的参数自动地帮助我们确定T的类型:

The second method is more common. Using type inference, the compiler automatically helps

us determine the type of T based on the parameters passed in:

let output=identity("mySomething");//string

使用泛型变量

Using generic variables

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

如果我们想同时打印出arg的长度。 我们很可能会这样做:

If we want to print the length of Arg at the same time. We are likely to do so:

function identity<T>(arg:T[]):T[]{
console.log(arg.length);
return arg;
}
function loggingIdentity<T>(arg:Array<T>):Array<T>{
console.log(arg.length);
return arg;
}

泛型类型

generic types

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

我们也可以使用不同的泛型参数名,只要在数量上和使用方式上能对应上就可以。

We can also use different generic parameter names as long as they correspond quantitatively and in terms of usage.

function identity<T>(arg:T):T{
return arg;
}
let myIdentity:<U>(arg:U)=>U=identity;

我们还可以使用带有调用签名的对象字面量来定义泛型函数:

We can also use object literals with call signatures to define generic functions:

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

这引导我们去写第一个泛型接口了。 我们把上面例子里的对象字面量拿出来做为一个接口:

This leads us to write the first generic interface. Let's take the literal quantities of the

objects in the example above as an interface:

interface GenericIdentityFn{
<T>(arg:T):T;
}
function identity<T>(arg:T):T{
return arg;
}
let myIdentity:GenericIdentityFn=identity;

一个相似的例子,我们可能想把泛型参数当作整个接口的一个参数。 这样我们就能清楚的知道使用的具体是哪个泛型类型。

For a similar example, we might want to consider generic parameters as a parameter of the entire interface. In this way,

we can clearly know which generic type we are using.

这样接口里的其它成员也能知道这个参数的类型了。

So that other members of the interface can also know the type of this parameter.

interface GenericIdentityFn<T>{
(arg:T):T;
}
function identity<T>(arg:T):T{
return arg;
}
let myIdentity:GeneratorFunction<number>=identity;//把非泛型函数签名作为泛型类型一部分

除了泛型接口,我们还可以创建泛型类。 注意,无法创建泛型枚举和泛型命名空间。

In addition to generic interfaces, we can also create generic classes. Note that generic enumerations and generic namespaces cannot be created.

泛型类

generic class

class GenericNumber<T>{
zeroValue:T;
add:(x:T,y:T)=>T;
}
let myGenericNumber=new GenericNumber<number>();
myGenericNumber.zeroValue=0;
myGenericNumber.add=function(x,y){return x+y;};

与接口一样,直接把泛型类型放在类后面,可以帮助我们确认类的所有属性都在使用相同的类型。

Just like interfaces, placing generic types directly behind classes can help us confirm that all attributes of classes use the same type.

泛型约束

Generic constraints

function loggingIdentity<T>(arg:T):T{
console.log(arg.length);
return arg;
}

我们定义一个接口来描述约束条件。 创建一个包含 .length属性的接口,使用这个接口和extends关键字还实现约束:

We define an interface to describe constraints. Create an interface with. length attributes, and use this interface

and extends keywords to implement constraints:

interface Lengthwise{
length:number;
}
function loggingIdentity<T extends Lengthwise>:T{
console.log(arg.length);
return arg;
}

在泛型约束中使用类型参数

Using type parameters in generic constraints

你可以声明一个类型参数,且它被另一个类型参数所约束。比如,

You can declare a type parameter and it is constrained by another type parameter. For example,

function find<T,U extends Findable>>(n:Text,s:U){

}
find(giraffe,myAnimals);

在泛型里使用类类型

Use class types in generics

function create<T>(c:{new():T;}):T{
return new c();
}

使用原型属性推断并约束构造函数与类实例的关系。

Use prototype attributes to infer and constrain the relationship between constructors and class instances.

class BeeKeeper {
hasMask: boolean;
} class ZooKeeper {
nametag: string;
} class Animal {
numLegs: number;
}
class Bee extends Animal {
keeper: BeeKeeper;
} class Lion extends Animal {
keeper: ZooKeeper;
} function findKeeper<A extends Animal, K> (a: {new(): A;
prototype: {keeper: K}}): K { return a.prototype.keeper;
} findKeeper(Lion).nametag;

by泛型这个不好懂啊,感觉也不好用啊

typescript泛型(学习笔记非干货)的更多相关文章

  1. typescript类(学习笔记非干货)

    我们声明一个 Greeter类.这个类有3个成员:一个叫做greeting的属性,一个构造函数和一个greet方法. We declare a Greeter class. This class ha ...

  2. typescript接口(学习笔记非干货)

    typescript的核心原则之一就是对所具有的shape类型检查结构性子类型化 One of the core principles of typescript is to check struct ...

  3. typescript基础类型(学习笔记非干货)

    布尔值 Boolean let isDone:boolean=false; 数字 Number let decLiteral:number=6; let hexLiteral:number=0xf00 ...

  4. typescript枚举,类型推论,类型兼容性,高级类型,Symbols(学习笔记非干货)

    枚举部分 Enumeration part 使用枚举我们可以定义一些有名字的数字常量. 枚举通过 enum关键字来定义. Using enumerations, we can define some ...

  5. typescript变量声明(学习笔记非干货)

    var a=10; function f(){ var message="hello,world"; return message; } function f(){ a=10; r ...

  6. mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)

    最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...

  7. typescript handbook 学习笔记4

    概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ...

  8. typescript handbook 学习笔记3

    概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ...

  9. typescript handbook 学习笔记2

    概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ...

随机推荐

  1. 插件GsonFormat快速生成JSon实体类

    IntelliJ IDEA 个人觉得是目前最好最强最智能的Java IDE,默认已经集成了几乎所有主流的开发工具和框架. 1.常用工具支持Java日常开发需要接触到很多常用的工具,为了便于使用,很多工 ...

  2. Ceph分布式存储-原理介绍及简单部署

    1)Ceph简单概述Ceph是一个分布式存储系统,诞生于2004年,最早致力于开发下一代高性能分布式文件系统的项目.Ceph源码下载:http://ceph.com/download/.随着云计算的发 ...

  3. proxy_pass反向代理配置中url后面加不加/的说明

    在日常的web网站部署中,经常会用到nginx的proxy_pass反向代理,有一个配置需要弄清楚:配置proxy_pass时,当在后面的url加上了/,相当于是绝对根路径,则nginx不会把loca ...

  4. js怎么将 base64转换成图片

    //获取数组最后一个元素 let hasFiles = files[Object.keys(files).pop()] // 参考上面的图片 let file = hasFiles.url let n ...

  5. BugPhobia发布篇章:Beta版本学霸在线系统正式发布

    0x00:测试报告版本管理 版本号 具体细节 修订时间 V 1.0 整理第一轮迭代用户管理和登陆注册的功能性验证测试,预计将继续网页对浏览器版本的兼容性测试 2015/11/12 V1.0.1 整理第 ...

  6. CSS字体大小之em,px,百分比

    首先要记住网页中常规字体的大小为16px. px是用来设置字体的绝对大小.通常为用于物理值的设置.我们在互联网上看到的常规字体大小为16px.而em是指相对于父元素的大小.1em是父元素的1倍,2em ...

  7. Docker(十六)-Docker的daemon.json的作用

    docker安装后默认没有daemon.json这个配置文件,需要进行手动创建.配置文件的默认路径:/etc/docker/daemon.json 一般情况,配置文件 daemon.json中配置的项 ...

  8. 设计模式之抽象工厂模式(附带类似反射功能的实现/c++)

    问题描述 假设我们要开发一款游戏, 当然为了吸引更多的人玩, 游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理).于是我们就可以采用这样一 ...

  9. scipy插值interpolation

    >>> from scipy.interpolate import interp1d#interp1d表示1维插值 >>> >>> x = np. ...

  10. 关于miniconda的安装,配置以及包批量安装和使用

    由于时间很晚了.就不写废话了. conda官方文档地址:http://conda.pydata.org/docs/ 一切其实都可以从miniconda的文档找到,这里只纪录自己操作的时候遇到的值得一说 ...