TypeScript应用

122 阅读3分钟

官方网站:www.typescriptlang.org/

TypeScript 是一个开源的编程语言,通过在 JavaScript(世界上最常用的语言之一) 的基础上添加静态类型定义构建而成。 类型提供了一种描述对象形状的方法。可以帮助提供更好的文档,还可以让 TypeScript 验证你的代码可以正常工作。

TypeScript 基础类型

Boolean 类型
Number 类型
String 类型
Array 类型
Enum 类型
Any 类型
Unknown 类型
Tuple 类型
Void 类型
Null 和 Undefined 类型
Never 类型

交叉类型 &

TypeScript 交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。

interface Person {
  id: string;
  age: number;
}

interface Worker {
  companyId: string;
}

type Staff = Person & Worker;

const staff: Staff = {
  id: 'E1006',
  age: 26,
  companyId: 'EFT'
};

在上面示例中,我们首先为 Person 和 Worker 类型定义了不同的属性,然后通过 & 运算符定义了 Staff 交叉类型,所以该类型同时拥有 Person 和 Worker 这两种类型的属性。

联合类型 |

TypeScript 联合类型表示的值是多种不同类型当中的某一个。联合类型放宽了类型的取值的范围,也就是说值的范围不再限于某个单一的数据类型。

let stringOrNumber: string | number = 0

stringOrNumber = ''
interface Motorcycle {
  type: 'motorcycle';
  color: string;
  make: number;
}

interface Car {
  type: 'car';
  color: string;
  persons: number;
}

type Vehicle = Motorcycle | Car;

function evaluatePrice(vehicle: Vehicle) {
    return vehicle.persons * 3.24
}

const car: Car = {type: 'car', color: 'red', persons: 7}

evaluatePrice(car)

image.png

类型守卫

类型保护是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。换句话说,类型保护可以保证一个字符串是一个字符串,尽管它的值也可以是一个数值。类型保护与特性检测并不是完全不同,其主要思想是尝试检测属性、方法或原型,以确定如何处理值。

in 类型映射

会遍历指定接口的 key 或者是遍历联合类型

interface Motorcycle {
  type: 'motorcycle';
  color: string;
  make: number;
}

interface Car {
  type: 'car';
  color: string;
  persons: number;
}

type Vehicle = Motorcycle | Car;

function evaluatePrice(vehicle: Vehicle) {
    if ('persons' in vehicle) {
        return vehicle.persons * 2.43
    }
    return vehicle.make * 3.53
}

const car: Car = {type: 'car', color: 'red', persons: 7}

evaluatePrice(car)

image.png

image.png

is 类型谓词

function isString(value: number | string): value is string {
    return typeof value === 'string';
}

function print(value: number | string) {
    if (isString(value)) {
        return value.split('').join(', ')
    }
    return value.toFixed(2)
}

typeof 原始类型

用来判断数据的类型是否是某个原始类型(number、string、boolean、symbol)并进行类型保护 但是 TypeScript 并不会阻止你与其它字符串比较,语言不会把那些表达式识别为类型保护。

function print(value: number | string) {
    if (typeof value === 'string') {
        return value.split('').join(', ')
    }
    return value.toFixed(2)
}

image.png

instanceof 关键字

与 typeof 类似,不过作用方式不同,instanceof 类型保护是通过构造函数来细化类型的一种方式。

其他关键字

keyof 索引类型查询操作符

可以用来一个对象中的所有 key 值:

interface Person {
    name: string;
    age: number;
}

type K1 = keyof Person;  'name' | 'key';
type K3 = keyof { [x: string]: Person };

T[K] 索引访问操作符

interface Person {
    name: string
    age: number
    gender: 'man' | 'women'
}

type NameType = Person['name']
type GenderType = Person['gender']

extends 类型约束

interface Person {
    name: string
    age: number
    gender: 'man' | 'women'
}

interface Student extends Person {
    studendNo: string;
}

const student: Student = {};
// Type '{}' is missing the following properties from type 'Student': studendNo, name, age, gender

infer 待推断类型

可以用 infer P 来标记一个泛型,表示这个泛型是一个待推断的类型,并且可以直接使用

type Foo<T> = T extends { a: infer U; b: infer U } ? U : never;

type T10 = Foo<{ a: string; b: string }>; // T10类型为 string
type T11 = Foo<{ a: string; b: number }>; // T11类型为 string | number

泛型工具

Readonly<T> 只读类型

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

Partial<T> 可选类型

type Partial<T> = {
    [P in keyof T]?: T[P];
};

Required<T> 必选类型

type Required<T> = {
    [P in keyof T]-?: T[P];
};

Extract<T, U> 摘取类型

type Extract<T, U> = T extends U ? T : never;

Exclude<T, U> 排除类型

type Exclude<T, U> = T extends U ? never : T;

Pick<T> 提取属性

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

Omit<T> 排除属性

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

Record<K, T> 属性映射

type Record<K extends keyof any, T> = {
    [P in K]: T;
};

ReturnType<T> 函数返回值类型

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

Parameters<T> 函数参数类型

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;