开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
前言
TS(TypeScript),借用TS官网上的描述,TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript。其实最开始,对于使用TS我内心是拒绝的,因为觉得在编写代码之前还需要先对变量类型进行定义,这不是浪费时间吗?但是在强迫自己使用一段时间,嗯,真香!话不多说,我们一起来看一下TS的用法吧。
TS基础用法
- 布尔值
const isBoolean: boolean = true;
- 数字
const age: number = 18;
- 字符串
const name: string = '小明';
// 使用模板字符串
const age: number = 18;
const nameAndAge: string = `小明${age}了`;
- 数组
// 在元素类型后面接上[]
const list: number[] = [1, 2, 3];
// 使用数组泛型,Array<元素类型>
const list: Array<number> = [1, 2, 3];
- 元组Tuple:允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
let list: [string, number];
list = ['hello', 18]; // OK
list = [18, 'hello']; // Error
- 枚举:允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
enum Color {Red, Green, Blue}
let c: Color = Color.Green; // 1
// 默认情况下,从0开始为元素编号,也可以手动指定成员的数值。
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green; // 2
// 或全部采用手动赋值
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green; // 2
// 可以由枚举的值得到它的名字
enum Color {Red = 1, Green = 2, Blue = 4}
let colorName: string = Color[2]; // 显示'Green' 因为上面代码里它的值是2
- any:yyds
let notSure: any = 4;
notSure = 'maybe a string instead';
notSure = false;
- unknown:安全类型的any。
let notSure: unknown = 4;
notSure = 'maybe a string instead';
notSure = false;
// 与any 类型的最大区别是:
// any 类型的变量使用了本身不存在的属性或者方法,在编译的时候,不会报错。
// 但是unknown 类型在编译的时候会报错。
- void:表示没有任何类型,通常一个函数没有返回值,通常会见到其返回类型是 void;
function warnUser(): void {
console.log('This is my warning message');
}
- null 和 undefined
let u: undefined = undefined;
let n: null = null;
// 默认情况下null 和 undefined 是所有类型的子类型,可以把null 和undefined 赋值给number类型的变量。
- never:表示的是那些永不存在的值的类型。never类型是任何类型的子类型,也可以赋值给任何类型;
// 推断的返回值类型为never
function fail() {
return error('Something failed');
}
- object:表示非原始类型。
declare function create(o: object | null): void;
create({ prop: 0 }); // OK
create(null); // OK
create(42); // Error
- 类型断言:通常发生在你清楚地知道一个实体具有比它现有类型更确切的类型。
// "尖括号"语法
let someValue: any = 'this is a string';
let strLength: number = (<string>someValue).length;
// as 语法
let someValue: any = 'this is a string';
let strLength: number = (someValue as string).length;
- interface:为类型命名和代码定义契约。
interface SquareConfig {
color?: string; // 可选属性
readonly x: number; // 只读属性
width: number; // 必填属性
[propName: string]: any; // 定义任意数量的其他属性
}
interface Shape {
color: string;
}
// 通过extends 继承,中间通过, 来间隔多个interface
interface Square extends SquareConfig, Shape {
sideLength: number;
}
function createSquare(config: SquareConfig): void {}
// 混合类型
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = <Counter>function (start: number) {};
counter.interval = 123;
counter.reset = function () {};
return counter;
}
- type:可以定义基础类型,联合类型或交叉类型。
interface Dog {
name: string;
}
interface Cat {
age: number;
}
type person = string;
type animal = Dog | Cat;
type animal = Dog & Cat;
- 泛型:一般使用泛型来创建可重用的组件。
// 返回值的类型与传入参数的类型相同。
function identity<T>(arg: T): T {
return arg;
}
// 传入所有的参数,包含类型参数
let output = identity<string>('myString');
// 类型推论
let output = identity('myString');
// 泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
return arg;
}
TS内置工具类型
注意:
类型
指的是TS类型(string, number, boolean...等),
属性
指的是对象身上的key。
- keyof:用来获取对应类型的属性key;
type A = number[];
const b: keyof A = 'length'; // concat, map, length... 等,数组的方法和属性。
// 等于
const b: 'length' | 'concat' | 'map' | ... = 'length';
- typeof: 用来判断对应变量的类型。
type A = number[];
const a: A = [0, 1];
const b: typeof a = [0];
// 等于
const b: A = [0];
- Record:定义一个对象的key 和 value 类型。
type Record<K extends string | number | symbol, T> = {
[P in K]: T;
}
- Partial: 生成一个新类型,该类型与传入的类型拥有相同的属性,但是所有的属性皆为可选项。
type Partial<T> = {
[P in keyof T]?: T[P];
}
- Required: 生成一个新类型,该类型与传入的类型拥有相同的属性,但是所有的属性皆为必选项。
type Required<T> = {
[P in keyof T]-?: T[P];
}
- Readonly: 生成一个新类型,该类型与传入的类型拥有相同的属性,但是所有的属性皆为只读。
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
- Pick: 生成一个新类型,该类型拥有T 中 K 属性集,新类型相当于T 与 K 的交集。
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
}
- Exclude: 从T 中剔除可以赋值给K 的类型。
// 需要注意的是,这里的extends 不能理解成继承,
// 对于使用extends关键字的条件类型(即上面的三元表达式类型),
// 如果extends前面的参数是一个泛型类型,当传入该参数的是联合类型,则使用分配律计算最终的结果
// 分配律是指,将联合类型的联合项拆成单项,分别代入条件类型,
// 然后将每个单项代入得到的结果再联合起来,得到最终的判断结果。
type Exclude<T, K> = T extends K ? never : T;
- Extract:提取T 中可以赋值给K 的类型。
type Extract<T, K> = T extends K ? T : never;
- Omit:生成一个新类型,该类型拥有T 中除了K 属性以外的所有属性。
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
- NonNullable:从T 中剔除null 和 undefined。
type NonNullable<T> = T extends null | undefined ? never : T;
- ReturnType:获得函数返回值类型。
type ReturnType<T extends (...args: any) : any> = T extends (...args: any) => infer R ? R : any;
- InstanceType:获取构造函数类型的实例类型。
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any
参考文档: