ts-Type Manipulation(类型操作)
1、Generics(泛型)- Types which take parameters
泛型type
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: <Type>(arg: Type) => Type = identity;
interface GenericIdentityFn {
<Type>(arg: Type): Type;
}
let myIdentity: GenericIdentityFn = identity;
let myIdentity: GenericIdentityFn<number> = identity;
泛型class
class GenericNumber<NumType> {
zeroValue: NumType;
add: (x: NumType, y: NumType) => NumType;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
return x + y;
};
一个类的类型有两个方面:静态方面和实例方面。泛型类仅在其实例方面而非其静态方面是通用的,因此在使用类时,静态成员不能使用类的类型参数。
约束
问题–仅仅想使用一部分类型,达到约束目的
function loggingIdentity<Type>(arg: Type): Type {
console.log(arg.length);
// Property 'length' does not exist on type 'Type'.
return arg;
}
解–通过extends做到满足约束条件
interface Lengthwise {
length: number;
}
function loggingIdentity<Type extends Lengthwise>(arg: Type): Type {
console.log(arg.length);
// Now we know it has a .length property, so no more error
return arg;
}
在泛型约束中使用Type 参数
// 通过传入的Type作为约束条件,对输入进行约束
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a");
getProperty(x, "m");
// Argument of type '"m"' is not assignable to parameter of type '"a" | "b" | "c" | "d"'.
在泛型中使用类类型
class BeeKeeper {
hasMask: boolean = true;
}
class ZooKeeper {
nametag: string = "Mikle";
}
class Animal {
numLegs: number = 4;
}
class Bee extends Animal {
keeper: BeeKeeper = new BeeKeeper();
}
class Lion extends Animal {
keeper: ZooKeeper = new ZooKeeper();
}
function createInstance<A extends Animal>(c: new () => A): A {
return new c();
}
createInstance(Lion).keeper.nametag;
createInstance(Bee).keeper.hasMask;
2、Keyof 操作符
拿到Point的key作为P的type
type Point = { x: number; y: number };
type P = keyof Point;
3、Typeof 操作符
和js中typeof相同
let s = "hello";
let n: typeof s;
// typeof仅可以作用基本类型,ReturnType获取type函数返回的类型
type Predicate = (x: unknown) => boolean;
type K = ReturnType<Predicate>;
function f() {
return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;
4、索引类型
使用对象字面量的key作为type
type Person = { age: number; name: string; alive: boolean };
type Age = Person["age"];
// 也可以使用number结合typeof,获取数组对象中key的type
const MyArray = [
{ name: "Alice", age: 15 },
{ name: "Bob", age: 23 },
{ name: "Eve", age: 38 },
];
type Person = typeof MyArray[number];
type Person = {
name: string;
age: number;
}
type Age = typeof MyArray[number]["age"];
5、条件类型
描述输入类型和输出类型的关系
interface Animal {
live(): void;
}
interface Dog extends Animal {
woof(): void;
}
type Example1 = Dog extends Animal ? number : string;
6、Mapped Types
见《ts–映射类型(Mapped Types)》