类型保护
in 操作符
用来判断某个属性是否在对象中
function move(pet: Fish | Bird) {
if ("swim" in pet) {
return pet.swim();
}
return pet.fly();
}
instanceof
Nullable Types
可选的参数的类型会被加上|undefined
,可以使用类型保护: typeof、in、?? 操作符、! 操作符
interface Vs type Aliases
接口跟类型别名很像,几乎所有接口具有的特性在类型别名中也可用,但是也有一些不同
- interface 可以通过 extends 继承来结合不同的 interface。type Aliases 可以通过 & 操作符类结合不同的 type Aliases
- interface 可以被类
implements
- type Aliases 在定义好之后就不能再改变了,不能再往其类型中添加新的类型。interface 则可以在通过一个类型上定义多次
// interface
interface Window {
title: string
}
interface Window {
ts: import("typescript")
}
const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
// type Aliases
type Window = {
title: string
}
type Window = {
ts: import("typescript")
}
// Error: Duplicate identifier 'Window'.
推荐尽可能使用 interface
This Type
class BasicCalculator {
public constructor(protected value: number = 0) {}
public add(operand: number): this {
this.value += operand;
return this;
}
public multiply(operand: number): this {
this.value *= operand;
return this;
}
// ... other operations go here ...
}
let v = new BasicCalculator(2).multiply(5).add(1)
Index types and index signatures
interface Dictionary<T> {
[key: number]: T;
}
let keys: keyof Dictionary<number>;
Mapped types
type Partial<T> = {
[P in keyof T]?: T[P];
// 不能添加一个成员
member: boolean; // Error
};
Note that this syntax describes a type rather than a member. If you want to add members, you can use an intersection type:
Conditional Types
T extends U ? X : Y // means when T is assignable to U the type is X, otherwise the type is Y.
// with the type argument A | B | C for T is resolved as (A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y).
// conditional Type 会被分散
type TypeName<T> = T extends string ? 'string' : T extends Function ? 'function' : 'object'
const a:TypeName<'ffds'|(()=>void)> // const a: "string" | "function"
// 用来过滤枚举
// Remove types from T that are assignable to U
type Diff<T, U> = T extends U ? never : T;
// Remove types from T that are not assignable to U
type Filter<T, U> = T extends U ? T : never;
Type inference
用来引用某个类型,从而可以使用该类型。
type returnType<T> = T extends (name: string) => infer R ? R : any // infer
type AFunc = (name: string) => boolean
type ARturnType = returnType<AFunc> // ARturnType 为 boolean
// 如果使用多次同一个 infer U ,U 的类型为联合类型
type Foo<T> = T extends { a: infer U; b: infer U } ? U : never; // U 为 a 的类型 | b 的类型