TypeScript 入门| 青训营笔记

61 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第4天

一、本堂课重点内容:

  1. TypeScript 历史及定义解析
  2. TypeScript 优势解读
  3. TypeScript 练习工具
  4. TypeScript 历史及定义解析
  5. TypeScript 优势解读
  6. TypeScript 练习工具

二、详细知识点介绍:

TypeScript 历史及定义解析

1.TypeScript 历史

image.png

2.TypeScript定义解析

  • 静态类型
    • 可读性增强:基于语法解析TSDoc,ide增强
    • 可维护性增强:在编译阶段暴露大部分错误
    • 在多人合作的大型项目中,获得更好的稳定性和开发效率
  • JS的超集
    • 包含于兼容所有JS特性,支持共存
    • 支持渐进式引入与升级

基本数据类型

image.png

对象类型

  • 可以自己创建一个自己想要的格式「类型」
const bytedancer: IBytedancer = {
  jobId: 9303245,
  name: 'Lin',
  sex: 'man',
  age: 28,
  hobby: 'swimming',
}
  • 一般这个IBytedancer前面有一个I,表示它是我们自定义得出的。
  • 还可以这样定义「使用interface
interface IBytedancer {
  readonly jobId: number;
  name: string;
  sex: 'man'|'woman'|'other';
  age: number;
  hobby?: string;
  [key: string]: any;
}

函数类型

function add(x: number, y: number): number { 
  return x + y; 
}
/*给基础数据类型做了一些限制,还有给函数的返回值做了一些限制*/
const mult: (x: number, y: number) => number = (x, y) => x * y

函数重载

function getDate(type: 'string', timestamp?: string): string;
interface IGetDate {
  (type: 'string', timestamp?: string): string;
  (type: 'date', timestamp?: string): Date;
  (type: 'string'|'date',timestamp?:string): Date | string;
}

数组类型

/*-   「类型 + 方括号」表示*/
type IArr1 = number[];
/*泛型表示*/
type IArr2 = Array<string | number | Record<string, number>>;
/*元组表示*/
type IArr3 = [number, number, string, string]
/*接口表示*/
interface IArr4 {
  [key: number]: any;
}

Typescript补充类型

/*空类型,表示无赋值*/
type IEmptyFunction = () => void;
/*任意类型,是所有类型的子类型*/
type IAnyType = any;
/*枚举类型:支持枚举值到枚举名的正,反向映射「仅有数字可以|字符串不行」*/
enum EnumExample { Mon, Tue, Wed, Thu, Fri, Sat, Sun }
EnumExample['Mon'] === 0
EnumExample[0] = 'Mon'
/*泛型*/
type INumArr = Array<number>;

Typescript泛型

function getRepeatArr(target) {
  return new Array(100).fill(target);
}

type IGetRepeatArr = (target: any) => any[];

/*不预先指定具体的类型,而在使用的时候再指定类型的一种特性*/
type IGetRepeatArrR = <T>(target: T) => T[];
/*泛型接口 & 多泛型*/
interface IX<T, U> {
  key: T;
  val: U;
}
/*泛型类*/
class IMan<T> {
  instance: T;
}
/*泛型别名*/
type ITypeArr<T> = Array<T>;

类型别名 & 类型断言

/*通过 `type` 关键字定义了 `IObjArr` 的别名。*/
type IObjArr = Array<{
  key: string;
  [objKey: string]: any;
}>

functiom keyBu<T extends IObjArr>(objArr: Array<T>) {
  const result = objArr.reduce((res, val, key) => {
    res[key] = val;
    return res;
  }, {});
  return result as Record<string, T>;
}

/*还可以直接用字面量来定义类型*/
type IDomTag = 'html' | 'body' | 'div' | 'span'
type IOddNumber = 1 | 2 | 3 | 4 | 5 | 7 | 9

联合/交叉类型

  • 联合类型:IAIB;联合类型表示一个值可以是几种类型之一
  • 交叉类型:IA&IB;多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性
type IBookList = Array<{
  author: string;
} & ({
  type: 'history';
  range: string;
} | {
  type: 'story';
  theme: string
})>

类型保护与类型守卫

interface IA {a: 1, a1: 2}
interface IB {b: 1, b1: 2}
/*类型守卫:定义一个函数,它的返回值是一个类型谓词,生效范围为子作用域*/
function getIsIA(arg: IA | IB): arg is IA {
  return !!(arg as IA).a;
}
// 再来判断是IA还是IB就不会出问题了
function log3(arg: IA | IB) {
  if (getIsIA(arg)) {
    console.log(arg.a1)
  } else {
    console.log(arg.b1)
  }
}

高级类型

/**
 * 实现merge函数类型
 * 要求sourceObj必须为targetObj的子集
 */
function merge1(sourceObj, targetObj) {
  // 扩展运算符拿出来这些东西
  const result = { ...sourceObj };
  for(let key in targetObj) {
    const itemVal = sourceObj[key];
    // 就是替换原本有的东西
    itemVal && (result[key] = itemVal);
  }
  return result;
}
// Question 不太懂这样做了有啥意义
function merge2(sourceObj, targetObj) {
  return { ...sourceObj, ...targetObj };
}
/*类型实现频繁:若obj类型较为复杂,则声明source和target便需要大量重复2遍
容易出错:若target增加/减少key,则需要source联动去除*/
interface ISourceObj {
  x?: string;
  y?: string;
}
interface ITargetObj {
  x: string;
  y: string;
}
type IMerge = (sourceObj: ISourceObj, targetObj: ITargetObj) => ITargetObj;