Visual LabINTERACTIVE LEARNING
JavaScript 内核第 1 / 5 章

配置与基础类型

从 tsconfig 开始,系统梳理 TypeScript 的主要类型。

TypeScript泛型类型体操
进阶预计 48 分钟查看源文 ↗

提示

js类型 缺失,ts作为js的超集,用于类型检查,提升开发效率和代码安全性,能及早发现错误

tsconfig 配置文件

.json .js .ts 三种文件格式都可以识别

🦄 提示

作用:

  1. 编译时选项,tsc 或者webpack中的ts-loader (实际在编译时使用的babel,这个文件不会影响)
  2. 代码编辑器的提示
{
"compilerOptions": {},
"files":[],//用于指定编译的文件数组,文件较少时使用
"include":['src/**/*.ts'],//包含的文件
"exclude":[],//优先于include,排除的文件
}

环境搭建

pnpm add typescript -g

pnpm add  ts-node  @type/node

类型推导

🎁 提示

声明变量的时候,直接赋值,会根据赋值的类型推导出标识符的类型注解,称为类型推导

  • let 声明的变量类型推导会是通用类型
  • const 声明的变量类型推导,推导出来的是字面量类型

type 数据类型

📌 提示

ts中有一些预先定义的类型 如 Iterable 可迭代类型

提示

注意! ts 中number小写,是指number类型

  • number 小写,ts 中的类型 js 中Number 是一个类,是用来创建实例的
  • Number 大写js 中的数据类 ,ts 中也可以用

🏆 提示

**类型推断:**ts 会自动推断变量的类型,如果定义时没有赋值,不管之后有没有赋值,都会被推断成 any 类型,会报错

布尔类型
let isEnd: boolean = false;
// isEnd只能是布尔类型,不能是其他类型
数字类型
let num: number = 2;
字符串类型
let str: string = "1";
数组类型
let arr: string[] = ["1"];
// 数组中只能放字符串

let arr1: Array<number> = [1, 2, 3];
// 写法2,很少用
void 类型
function getData(a: string | number, b: string): void {
  console.log("void");
}
// void类型的变量只能赋值为undefined和null 没有返回值的函数
//一个函数没有返回值时,返回值是void
//通常使用在定义函数的数据类型的地方使用
type func:()=> void

//当基于上下文类型推导中的函数,推导出来的函数返回值是viod时,如果返回一个值,并不会报错
对象类型
let obj:{name:string} = {
  name: 123,
};

// 直接写,利用类型推导,不要直接这样写
元组类型
let tuple: [string, number] = ["1", 2];
// 元组类型注意注解的格式,同时必须对应赋值,注意写法,类型写在中括号中
// 函数中使用元组最多,如react中使用useState
any 类型
let mar: any = 1;
// 任意类型,当无法确定类型的时候,或者后面可能会发生改变的时候,使用该类型
//不要滥用any类型,回到js
//做任何操作都是合法的
undefined 类型
// 只有一个值就是undefined
unknown 类型
// 不确定的类型
//和any 的类型的相似,区别是的,unknown类型上做任何操作都是非法的,需要先进行类型缩小,再进行对应操作
never 类型
// 永远不能赋值的类型
//用来先设置,或者函数中有死循环,或者函数中有报错,都会报错
//一般自己不会主动定义,封装工具库时会使用
handleMessage(msg:string|number){
switch(typeof msg){
  case 'String':
     console.log(msg.length)
  case 'Number':
     console.log(msg)
  default:
     const check:never = msg
  }
}

//一旦需要扩展handleMessage方法时,添加了类型,而忘记添加实现,则会报错,增加代码的严谨性
枚举类型
//重要
// type Direction = "left" | "Right" | "Top" | "Bottom"
//LEFT=0  RIGHT=1  TOP=2  BOTTOM=3 这里是有默认值的,实际会对应到一个数值,并且可以赋值
enum Direction {
  LEFT, //LEFT=1,后面可以递增
  RIGHT,
  TOP,
  BOTTOM,
}

function turnDirection(direction: Direction) {
  switch (direction) {
    case Direction.LEFT:
      console.log("改变角色的方向向左");
      break;
    case Direction.RIGHT:
      console.log("改变角色的方向向右");
      break;
    case Direction.TOP:
      console.log("改变角色的方向向上");
      break;
    case Direction.BOTTOM:
      console.log("改变角色的方向向下");
      break;
    default:
      const foo: never = direction;
      //   never的典型应用 当Direction 新增选项而turnDirection没有增加对应代码的时候,会报错
      break;
  }
}

turnDirection(Direction.LEFT);
turnDirection(Direction.RIGHT);
turnDirection(Direction.TOP);
turnDirection(Direction.BOTTOM);
null 类型
// 只有一个值就是null
函数参数的类型
function getData(num: number, str: string): string {
  return num + str;
}
// 函数参数的类型 会做提示
// 作为参数的匿名函数可以不做注解
// 函数的参数对象类型
function getData(obj: { num: number; str?: string }): string {
  console.log(obj.str);
  return obj.num + "";
}

//可选参数的类型,是一个联合类型  原本的类型和 undefined

//默认参数的类型也是联合类型,因为调用的时候也可以传入undefined

//剩余参数的类型注解需要写成数组  
联合类型 和交叉类型
// 用竖线隔开,并集,联合类型,满足其中一种类型即可
number | string | boolean;

//交叉类型 多个类型都需要满足
interface IPerson {
name: string
}

interface IStudent{
 age:number
}
//既需要满足IPerson 也需要满足IStudent
type Ikun = IPerson & IStudent
可选类型
// 参数即为可选
function(message?:string){

}
字符串字面量类型
let myName: "Tom" = "Tom";

type EventNames = "click" | "scroll" | "mousemove";
let event = "click";
// 意义在于结合联合类型才有意义

// 字面量推理
type Request = {
  url: string;
  method: Method;
};

type Method = "GET" | "POST";

const options: Request = {
  // 方法一
  url: "http://baidu.com",
  method: "POST",
} as const; //方法二

// as const 会将options的属性变成只读属性,否则method是字面量类型,option里的method是string类型,
//会报错

function getData(url: string, method: Method) {}

getData(options.url, options.method);
函数类型
//ts对传入的函数参数个数不校验!!!,能少不能多

//函数本身也是一个标识符,自身也有类型
//方案一、函数类型表达式(arg:string)=> void  没有返回值
type addFn = (num:sting,str:number) => void
const  add:addFn = function(num:sting,str:number){
    return num+str
}
//方案二、函数调用签名 (从对象的角度看函数),当需要描述函数其他属性时,使用

interface IFunc {
name:string
(num:number):void //调用签名
new ():Person  //构造签名
}

const  printNumber:IFunc = function(num:number){
}