TS 总结

315 阅读3分钟

小知识,大挑战!本文正在参与“  程序员必备小知识  ”创作活动

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

类型注解和编译时类型检查

使⽤类型注解约束变量类型,编译器可以做静态类型检查,使程序更加健壮

类型基础

// ts-test.ts
let var1: string; // 类型注解
var1 = "ts 总结"; // 正确
var1 = 4; // 错误
// 编译器类型推断可省略这个语法
let var2 = true;
// 常⻅原始类型: string,number,boolean,undefined,null,symbol
// 类型数组
let arr: string[];
arr = ['Tom']; // 或Array<string>
// 任意类型any
let varAny: any;
varAny = 'xx';
varAny = 3;
// any类型也可⽤于数组
let arrAny: any[];
arrAny = [1, true, "free"];
arrAny[1] = 100;
// 函数中的类型约束
function greet(person: string): string {
 return 'hello, ' + person;
}
// void类型,常⽤于没有返回值的函数
function warn(): void {}

类型别名

使⽤类型别名⾃定义类型

// 可以⽤下⾯这样⽅式定义对象类型
const objType: { foo: string, bar: string }
// 使⽤type定义类型别名,使⽤更便捷,还能复⽤
type Foobar = { foo: string, bar: string }
const aliasType: Foobar

联合类型

希望某个变量或参数的类型是多种类型其中之⼀

let union: string | number;
union = '1'; // ok
union = 1; // ok

交叉类型

想要定义某种由多种类型合并⽽成的类型使⽤交叉类型

type First = {first: number};
type Second = {second: number};
// FirstAndSecond将同时拥有属性first和second
type FirstAndSecond = First & Second;

函数

必填参:参数⼀旦声明,就要求传递,且类型需符合

function greeting(person: string): string {
 return "Hello, " + person;
}
greeting('tom')

可选参数:参数名后⾯加上问号,变成可选参数

function greeting(person: string, msg?: string): string {
 return "Hello, " + person;
}

默认值

function greeting(person: string, msg = ''): string {
 return "Hello, " + person;
}

函数重载:以参数数量或类型区分多个同名函数

// 重载1
function watch(cb1: () => void): void;
// 重载2
function watch(cb1: () => void, cb2: (v1: any, v2: any) => void): void;
// 实现
function watch(cb1: () => void, cb2?: (v1: any, v2: any) => void) {
 if (cb1 && cb2) {
 console.log('执⾏watch重载2'); 
 } else {
 console.log('执⾏watch重载1'); 
 }
}

ts中的类和es6中⼤体相同,这⾥重点关注ts带来的访问控制等特性

class Parent {
 private _foo = "foo"; // 私有属性,不能在类的外部访问
 protected bar = "bar"; // 保护属性,可以在⼦类中访问
 // 参数属性:构造函数参数加修饰符,能够定义为成员属性
 constructor(public tua = "tua") {}
 // ⽅法也有修饰符
 private someMethod() {}
 // 存取器:属性⽅式访问,可添加额外逻辑,控制读写性
 get foo() {
 return this._foo;
 }
 set foo(val) {
 this._foo = val;
 }
}

接⼝

接⼝仅约束结构,不要求实现,使⽤更简单

// Person接⼝定义了解构
interface Person {
 firstName: string;
 lastName: string;
}
// greeting函数通过Person接⼝约束参数解构
function greeting(person: Person) {
 return 'Hello, ' + person.firstName + ' ' + person.lastName;
}
greeting({firstName: 'Jane', lastName: 'User'}); // 正确
greeting({firstName: 'Jane'}); // 错误

泛型

泛型(Generics)是指在定义函数、接⼝或类的时候,不预先指定具体的类型,⽽在使⽤的时候再指定 类型的⼀种特性。以此增加代码通⽤性。

// 不⽤泛型
// interface Result {
// ok: 0 | 1;
// data: Feature[];
// }
// 使⽤泛型
interface Result<T> {
 ok: 0 | 1;
 data: T;
}
// 泛型⽅法
function getResult<T>(data: T): Result<T> {
 return {ok:1, data};
}
// ⽤尖括号⽅式指定T为string
getResult<string>('hello')
// ⽤类型推断指定T为number
getResult(1)

泛型优点:

  • 函数和类可以⽀持多种类型,更加通⽤
  • 不必编写多条重载,冗⻓联合类型,可读性好
  • 灵活控制类型约束 不仅通⽤且能灵活控制,泛型被⼴泛⽤于通⽤库的编写。