TS基础用法

105 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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

参考文档:

www.tslang.cn/docs/handbo…