JavaScript 内核第 1 / 5 章
配置与基础类型
从 tsconfig 开始,系统梳理 TypeScript 的主要类型。
⚽ 提示
js类型 缺失,ts作为js的超集,用于类型检查,提升开发效率和代码安全性,能及早发现错误
tsconfig 配置文件
.json .js .ts 三种文件格式都可以识别
🦄 提示
作用:
- 编译时选项,tsc 或者webpack中的ts-loader (实际在编译时使用的babel,这个文件不会影响)
- 代码编辑器的提示
{
"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){
}