从官方文档 Type Manipulation 开始学习ts
ts很牛B,因为在ts中可以:类型A由类型B计算得出。 “类型” 像值一样,能通过 操作符被计算。ts中有专门的类型操作符(type operators)。 这种思想最简单的体现就是泛型。
Generics 泛型
定义对象的类型时使用类型变量(泛型参数),即泛型(generic)。泛型让类型不再写死(hard code)。泛型用来让类型可重用(reusable)。
function identity<Type>(arg: Type): Type {
return arg;
}
为了不写死,就必须引入变量机制(参数机制)。这里,Type就是变量(参数)。这种值是类型的变量,称为类型变量(type variable)。定义函数时,定义函数类型,如果使用类型变量定义函数类型,这种函数就是泛型函数(generic functions)。
在定义函数类型时使用了类型变量,那么,在调用函数时要传入相应的类型值。如 identity 函数被调用,传入string作为类型变量的类型值:
let output = identity<string>("myString");
当类型值可以由值 ( "myString" ) 计算得出的时候(type argument inference),可以不传入类型值。
let output = identity("myString");
什么是Array<Type> ?
function loggingIdentity<Type>(arg: Array<Type>): Array<Type> {
return arg;
}
Array<Type>是使用了类型变量的类型定义,就是所谓的泛型定义。泛型定义Array<Type>的输出类型由泛型定义Array<Type>和类型变量Type的类型值计算得出。
以下几种定义类型的语法的语义是相同:
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: { <Type>(arg: Type) : Type } = identity;// as a call signature of an object literal type
let myIdentity: <Type>(arg: Type) => Type = identity;
interface GenericIdentityFn {// interface是对对象进行类型定义
<Type>(arg: Type) : Type;// 在类型定义中使用类型变量(泛型)
}
interface GenericIdentityFn<Type> {// 类型变量升域,升域到interface级别
(arg: Type) : Type;
}
let myIdentity: GenericIdentityFn = identity;
let myIdentity: GenericIdentityFn<number> = identity;
像泛型函数的情况一样,在定义类时,定义类的类型时,使用泛型参数,这种类就是泛型类(generic classes)
class GenericNumber<NumType> { // NumType是泛型参数
zeroValue: NumType;
add: (x: NumType, y: NumType) => NumType;
}
由类型来约束类型
到目前为止,我们知道由类型来约束值,可以使得值必须满足该类型。其实,类型也可以约束类型,使得类型必须满足另一类型。这样,形成类型A约束类型B,类型B再约束值C的约束链路。约束类型B的类型A可以是interface(类型):
interface Lengthwise {// Lengthwise === 类型A
length: number;
}
function loggingIdentity<Type extends Lengthwise>(arg: Type): Type {
console.log(arg.length);
return arg;
}
类型A可以是类型变量:
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {// 类型变量Type === 类型A
return obj[key];
}
类型A可以是类对象(值):
class Animal {// Animal === 类型A
numLegs: number = 4;
}
function createInstance<A extends Animal>(c: new () => A): A {
return new c();
}