泛型
泛型类型
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: <Type>(arg: Type) => Type = identity;
interface GenericIdentityFn {
<Type>(arg: Type): Type;
}
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: GenericIdentityFn = 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;
};
let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function (x, y) {
return x + y;
};
泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<Type extends Lengthwise>(arg: Type): Type {
return arg;
}
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
// ok
getProperty(x, "a");
// error
getProperty(x, "m");
泛型中使用class类型
function create<Type>(c: { new (): Type }): Type {
return new c();
}
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;
keyof类型操作符
type Point = { x: number; y: number };
// 等于 “x” | “y”
type P = keyof Point;
type Arrayish = { [n: number]: unknown };
// type A = number
type A = keyof Arrayish;
type Mapish = { [k: string]: boolean };
// type M = string | number
type M = keyof Mapish;
obj[0] 会转为obj["0"]所以类型M也可能是number类型
typeof类型操作符
在类型的上下文中,使用typeof操作符来获取变量或者属性的类型
let s = "hello";
// let n: string
let n: typeof s;
索引类型
type Person = { age: number; name: string; alive: boolean };
// type Age = number
type Age = Person["age"];
// type I1 = string | number
type I1 = Person["age" | "name"];
// type I2 = string | number | boolean
type I2 = Person[keyof Person];
type AliveOrName = "alive" | "name";
// type I3 = string | boolean
type I3 = Person[AliveOrName];
条件类型
使用三目
SomeType extends OtherType ? TrueType : FalseType;
interface Animal {
live(): void;
}
// type Example1 = number
type Example1 = Dog extends Animal ? number : string;
条件类型约束
type MessageOf<T> = T extends { message: unknown } ? T["message"] : never;
interface Email {
message: string;
}
interface Dog {
bark(): void;
}
// type EmailMessageContents = string
type EmailMessageContents = MessageOf<Email>;
// type DogMessageContents = never
type DogMessageContents = MessageOf<Dog>;
条件类型内的推导
使用infer关键字
type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;
// (...args: never[]) => infer Return
type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
? Return
: never;
// type Num = number
type Num = GetReturnType<() => number>;
// type Str = string
type Str = GetReturnType<(x: string) => string>;
// type Bools = boolean[]
type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>;
分布条件类型
type ToArray<Type> = Type extends any ? Type[] : never;
// type StrArrOrNumArr = string[] | number[]
type StrArrOrNumArr = ToArray<string | number>;
映射类型
映射类型基于索引签名
type OnlyBoolsAndHorses = {
[key: string]: boolean | Horse;
};
const conforms: OnlyBoolsAndHorses = {
del: true,
rodney: false,
};
type OptionsFlags<Type> = {
[Property in keyof Type]: boolean;
};
映射修饰符
可以通过+ -添加或者移除? readonly
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property];
};
type LockedAccount = {
readonly id: string;
readonly name: string;
};
// type UnlockedAccount = { id: string; name: string; }
type UnlockedAccount = CreateMutable<LockedAccount>;
// Removes 'optional' attributes from a type's properties
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
type MaybeUser = {
id: string;
name?: string;
age?: number;
};
// type User = { id: string; name: string; age: number; }
type User = Concrete<MaybeUser>;
通过as重命名映射类型的key
type Getters<Type> = {
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};
interface Person {
name: string;
age: number;
location: string;
}
// type LazyPerson = { getName: () => string; getAge: () => number; getLocation: () => string; }
type LazyPerson = Getters<Person>;
// Remove the 'kind' property
type RemoveKindField<Type> = {
[Property in keyof Type as Exclude<Property, "kind">]: Type[Property]
};
interface Circle {
kind: "circle";
radius: number;
}
// type KindlessCircle = { radius: number; }
type KindlessCircle = RemoveKindField<Circle>;
模板字面量类型
type World = "world";
// type Greeting = "hello world"
type Greeting = `hello ${World}`;
type PropEventSource<Type> = {
on(eventName: `${string & keyof Type}Changed`, callback: (newValue: any) => void): void;
};
/// Create a "watched object" with an 'on' method
/// so that you can watch for changes to properties.
declare function makeWatchedObject<Type>(obj: Type): Type & PropEventSource<Type>;
const person = makeWatchedObject({
firstName: "Saoirse",
lastName: "Ronan",
age: 26
});
person.on("firstNameChanged", () => {});
// error, Prevent easy human error (using the key instead of the event name)
person.on("firstName", () => {});
内置的操作类型
Uppercase<StringType>Lowercase<StringType>Capitalize<StringType>Uncapitalize<StringType>