TypeScript
2022-07-09· 20min
TypeScript,一种基于 JavaScript 的强类型编程语言
#开发优势
- 类型安全,在编码阶段避免潜在的编码错误
- 更好的 IDE 支持,如代码跳转定义、补全提示等
- 强大的类型系统,对于大型项目、多人协同编码时,使代码更具可读性、可维护性
#语法小结
#数据类型
- 支持 JavaScript 数据类型:基础数据类型、引用数据类型
- Enum 枚举
enum Color { Red = 1, Green, Blue, } let cName1: string = Color[2]; let cName2: number = Color.Green; console.log(cName1, cName2); // Green, 2 - Tuple 元组
let arrT: [string, number] = ["hello", 10]; - Any
- 用于描述任意类型的变量,不作任何约束,跳过编译阶段的检查
let v: any = "string"; v = false; - Void
- 表示无任何类型
// 如:没有返回值的函数的返回值类型 function fn(): void { console.log("No return"); } - Never
- 表示的是那些永不存在的值的类型
- 是任何类型的子类型,也可以赋值给任何类型
// 抛出异常 function error(message: string): never { throw new Error(message); // 抛出异常会直接中断程序运行,即永不存在返回(具有不可达的终点) } // 死循环 function loopForever(): never { while (true) {} // 程序无法运行到函数返回值那一步,即永不存在返回 } - Unknown
- 表示未知类型
let v: unknown = "string"; v = false;
#类型限定
- 类型推断
// TS 可以自动推断出变量的类型
let str = "ssss";
str = 10; // Type 'number' is not assignable to type 'string'.
- 类型注解
let str: string = "ssss";
- 类型断言
let str: any = "ssss";
// as关键字
let strLen: number = (str as string).length;
// 尖括号语法
let strLen: number = (<string>str).length;
#关键字
#keyof
- 用于获取某个类型的所有键,并将其作为联合类型返回
interface Person {
name: string;
slogan: number;
}
type PersonKeys = keyof Person; // "name" | "slogan"
#in
- 用于创建映射类型时,遍历联合类型中的每个成员
// 例子一:
type PersonKeys = "name" | "slogan";
type Person1 = {
[K in PersonKeys]: string | number;
};
// 同下:
type Person1 = {
name: string | number;
age: string | number;
};
// 例子二:
type Person2 = {
name: number;
age: number;
};
type Person3 = {
[K in keyof Person2]: string;
};
// 同下:
type Person3 = {
name: string;
age: string;
};
#keyof
- 用于获取变量或表达式的类型
// 例子一:
let personName = "Alice";
type NameType = typeof personName; // string
// 例子二:
const person3 = {
name: "str",
};
type PersonType = typeof person3;
// 等同于:
type PersonType = {
name: string;
};
#infer
- 用于在条件类型中进行类型推断。在条件类型中提取并命名一个类型,然后在该条件类型的返回部分中使用。
type ParamType<T> = T extends (arg: infer P) => any ? P : T;
interface Person {
name: string;
}
type MyFn = (person: Person) => void;
type ParamPenson = ParamType<MyFn>; // Person
type ParamStr = ParamType<string>; // string
#extends
- 类型组合
interface N1 {
name: string;
}
type S1 = {
slogan: string;
};
interface NS extends N1, S1 {}
let ns1: NS = {
name: "p1",
slogan: "s1",
};
- 类型约束
type IsStr<T> = T extends string ? true : false;
type Box<T> = {
val: T;
isString: IsStr<T>;
};
const stringBox: Box<string> = {
val: "str",
isString: true,
};
- 继承
class Person1 {
public name: string = "str";
}
class Person2 extends Person1 {
public slogan: string = "sl1";
}
const pp = new Person2();
console.log(pp.slogan); // sl1
#工具类型
#Partial<T>
// 定义:将 T 中所有的属性都变成可选类型
type Partial<T> = {
[P in keyof T]?: T[P];
};
// 示例
type Person = {
name: string;
slogan: string;
};
const Person2: Partial<Person> = {
name: "p2",
};
#Pick<T, K>
// 定义:从 T 中摘取部分属性
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
// 示例
type Person = {
name: string;
slogan: string;
sex: string;
};
const Person3: Pick<Person, "name" | "sex"> = {
name: "p3",
sex: "male",
};
#Exclude<T, U>
// 定义:从 T 中剔除可以赋值给 U 的类型
// 条件类型,如果 T 可以分配给 U,则是 never,否则是 T
type Exclude<T, U> = T extends U ? never : T;
// 示例
type Ta = string | number;
type Tb = number;
type Tc = Exclude<Ta, Tb>;
const tc1: Tc = "str";
#Extract<T, U>
// 定义:提取 T 中可以赋值给 U 的类型
type Extract<T, U> = T extends U ? T : never;
// 示例
type Ta = string | number;
type Tb = number;
type Tc = Extract<Ta, Tb>;
const tc1: Tc = 1;
#Omit<T, K>
// 定义:从 T 中排除部分属性
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
// 示例
type Person = {
name: string;
slogan: string;
};
const Person4: Omit<Person, "slogan"> = {
name: "p4",
};
#Readonly<T>
// 定义:将 T 的所有属性变为只读属性
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
// 示例
type Person = {
name: string;
};
type PersonReadonly = Readonly<Person>;
const person: PersonReadonly = {
name: "p6",
};
person.name = "p8"; // Cannot assign to 'name' because it is a read-only property.
#Required<T>
// 定义:将 T 中所有的属性都变成必选类型
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
// 示例
type Person = {
name: string;
};
type PersonReadonly = Readonly<Person>;
const person: PersonReadonly = {
name: "p5",
};
person.name = "p6"; // Cannot assign to 'name' because it is a read-only property.
#Record<K, T>
// 定义:返回属性名为 K,属性值为 T 的类型
type Record<K extends keyof any, T> = {
[P in K]: T;
};
// 示例
type Str2Num = Record<string, number>;
const str2num: Str2Num = {
a: 1,
b: 2,
c: 3,
};
#Parameters<T>
// 定义:获取函数参数类型组成的元组
type Parameters<T extends (...args: any) => any> = T extends (
...args: infer P
) => any
? P
: never;
// 示例
type MyFn = (a: number, b: string) => void;
type MyFnParameters = Parameters<MyFn>; // [number, string]