TypeScript完全解读
本文主要是从一个项目的角度来对typescript从无到有进行解读,若有不当或者不对之处,敬请指教。持续更新中...
1. 初始化
- 初始化项目:
npm init -y
- 全局安装ts依赖:
npm install typescript tslint -g
- ts初始化:
tsc --init
- 安装webpack:
npm install webpack webpack-cli webpack-dev-server -D
2. vscode需要安装的插件
- TSLint
- TSLint (deprecated)
- TSLint Vue
- TSLint Snippets
- TSLint Vue-TSX
- json to TS 将json类型的数据 直接生成ts的类型
- Settings Sync 配置github保存
- 图像预览工具:Image preview
3. ts的基础类型
3.1. 布尔值(和其他语言中一样)
let isDone: boolean = false;
3.2. 数字(ts中所有的数字类型都是number)
let num: number = 123
num = 12.3
num = 0b11;
num = 0o111;
num = 0x11;
复制代码
3.3. 字符串类型(可以使用双引号,单引号,反引号来表示字符串)
let num1 = 12
let str: string;
str = 'abc';
str = `数值:${num1}`
复制代码
3.4. 数组类型(有两种定形式,一种是在元素类型后边添加[],一种是使用泛型 Array[元素类型])
// 元素后边添加[]类型
let arr1: number[];
let arr2: (string | number)[];
// 使用泛型 Array[元素类型]
let arr3: Array<number>;
let arr4: Array<string | number>;
// 调用
arr1 = [1];
arr2 = [1, 'a']
复制代码
3.5. 元组Tuple类型(表示一个已知元素数量和类型的数组,各元素的类型不必相同)
let tuple: [string, number, boolean];
tuple = ['a', 1, false]
复制代码
3.6. 枚举类型(不设置初始值,自动从0开始,也可以自定义设置默认值)
enum Roles {
ADMIN,
USER = "admin",
}
复制代码
3.7. any类型(尽量少用,否则ts将完全没有价值)
let value:any = 'abc'
3.8. void类型(没有返回值 默认返回值是undefine)
某种程度上void类型和any类型相反;此外声明一个void类型没有太大意义没因为它只能赋值undefined和null
const consoleText = (text: string): void => {
console.log(text)
}
let unable:void = undefined | void;
复制代码
3.9. Null和Undifined类型(是所有类型的子类型,其他值都是可以被赋值为null或undefined)
let u: undefined;
u = undefined;
let n: null;
n = null;
复制代码
3.10. Never类型(永不存在的值的类型)
一般情况下错误类型和死循环 抛出的是never类型
// never类型 是不存在的类型
const errorFun = (message: string): never => {
throw new Error(message)
}
//-死循环也是抛出的never类型
const infiniteFunc = (): never => {
while (true) { }
}
复制代码
3.11 Object类型
object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。
3.12 断言(已经确定的类型)
断言有两种形式:一种尖括号
语法;一种as
语法
// 获取一个数据的长度
const getLenght = (target: string | number) => {
if ((<string>target).length || (target as string).length === 0) {
return (target as string).length
} else {
return target.toString().length
}
}
复制代码
注意:当在TypeScript里使用JSX时,只有 as语法断言是被允许的。
3.13 symbol类型
- symbol是新增的一种类型,表示独一无二的值
- symbol的值不可以与其他数据类型做运算
4. 函数
函数有两种定义方式:分别是使用字面量方式和关键字Function方式
const func = funct(){}
function func(){}
复制代码
5. 高级类型
5.1 交叉类型
交叉类型一般使用&
符号来连接两个类型。相对于并集取值。
const mergeFunc = <T, U>(arg1: T, arg2: U): T & U => {
// let res = {} as T&U;
// let res = <T&U>{};
let res = Object.assign(arg1, arg2);
return res;
复制代码
5.2 联合类型
联合类型一般使用|
符号来标识。相当于或的关系
let number: string | number;
// 获取长度的方法
const getLengthFunc = (content: string | number) => {
if (typeof content === "string") return content.length;
else return content.toString().length;
};
复制代码
5.3 类型保护法
一般情况是有两种以上类型的时候,会做类型的判断,会导致类型报错。通常是有typeof
和 instanceof
两个类型判断语句进行。
- typeof:只能作为等于或者不等于的操作,其他的规则不提供类型保护;运算的类型只鞥是以下四种类型中的一种:
string/number/boolean/symbol
- instanceof 类型保护效果,可使用上边非四种类型外的其他类型。
5.4 类型确定用法
在开发的过程中,确定某一种类型是什么,但是编辑器仍会报错,此时便可以用 !
符号来使用类型断言,表示一定是这一个类型。
function getSplicedStr(num: number | null): string {
function getRes(prefix: string) {
// !此处表示一定是这个数据类型
return prefix + num!.toFixed().toString();
}
num = num || 0.0;
return getRes("sub_");
}
复制代码
5.5 字符串字面量类型
在一些已确定的类型中使用字符串字面量 来定义类型,避免出现字面量以外的类型。数字字面量类型与字符串类字面量基本类似
。
// 定义了一个方向的字符串字面量类型
type Direction = "north" | "east" | "south" | "west";
// 获取第一个字母
function getDirectionFirstLetter(direction: Direction): string {
return direction.substr(0, 1);
}
// 调用 只能输入定义的字面量类型
getDirectionFirstLetter("north");
复制代码
5.6 可辨识联合类型
可辨识联合类型的两个要素:
-
- 具有普通的单例类型属性;
-
- 一个类型别名包含了那些类型的联合
以下是一个圆形、矩形、长方形
求面积的一个实例:
// 定义正方形的接口
interface Square {
kind: "square";
size: number;
}
// 定义一个长方形的接口
interface Rectangle {
kind: "rectangle";
height: number;
width: number;
}
// 定义一个圆形的接口
interface Circle {
kind: "circle";
radius: number;
}
// 将三种类型的接口 定义为一个字符串字面量类型
type Shape = Square | Rectangle | Circle;
// 非其他上述三种类型外的其他类型。
function asserNever(value: never): never {
throw new Error("Unexpected Object:" + value);
}
//求各种类型的面积方法
function getArea(s: Shape): number {
switch (s.kind) {
case "square":
return s.size * s.size;
case "rectangle":
return s.height * s.width;
case "circle":
return Math.PI * s.radius ** 2;
default:
return asserNever(s);
}
}
复制代码
5.7 索引类型
索引类型主要分为两部分,分别是索引类型查询和索引访问。
- 索引查询
- 索引查询使用操作符
keyof
可以生成一个字面量类型的联合类型。
- 索引查询使用操作符
- 索引访问
- 索引访问使用操作符
[]
,可以获取单个的属性值,也可以获取一组属性值
- 索引访问使用操作符
5.8 映射类型
映射类型:可以用过一个旧类型转换成一个新的类型。
映射中提供了一些内置的方法:readonly
,partail
,pick
,record
-
readonly
:表示将所有的属性变成只读type inner_readOnly = Readonly<oldInfoType>;
-
partail
:表示将所有的数据变成可选type inner_readOnly = Partail<oldInfoType>;
-
pick
:表示获取对象的部分属性 -
record
适用于将一个对象中的每一个属性 转换成其他值得一个场景
5.9 增加或移除特定修饰符
可以使用 +
, -
来添加或者删除特殊修饰符 默认是添加 +
type oldInfoMap<T> = {
+ readonly [P in keyof T]-?: T[P]; // in 表示循环
};
复制代码
5.10 unknown 类型
-
任何类型都可以赋值给unknown类型
let value1: unknown; value1 = 11; value1 = "aaa"; 复制代码
-
如果没有类型断言或基于控制流的类型细化时,unknown 不可以赋值给其他类型,此时他只能赋值给unknown自身 和any 类型。
let value2: unknown; // error:不能将类型“unknown”分配给类型“string” // let value3:string = value2; 复制代码
-
如果没有类型断言或基于控制流的类型细化时,不能在他上面进行任何操作
let value4: unknown; // error:对象的类型为 "unknown" // value4+=1; 复制代码
-
unknown 与任何其他类型组成的交叉类型,最后等于其他类型
type type1 = string & unknown; type type2 = number & unknown; type type3 = unknown & unknown; type type4 = string[] & unknown; 复制代码
-
unknown 与任何其他类型(除了any)组成的联合类型,都等于unknown类型
type type5 = string | unknown; type type6 = any | unknown; type type7 = string[] | unknown; 复制代码
-
never 类型是 unknown的子类型
type type8 = never extends unknown ? true : false; 复制代码
-
keyof unknown 等于类型 never
type type9 = keyof unknown; 复制代码
-
只能对unknown进行等或不等操作,不能进行其他操作
value1 === value2; value1 !== value2; 复制代码
-
unknown 类型的值不能访问他的属性、不能作为函数调用和作为类创建实例
let value10: unknown; // value10.name= '' // value10() // new value10() 复制代码
-
使用映射类型时如果遍历的是unknown类型,则不会映射任何属性
type types1<T> = { [P in keyof T]: number; }; type type10 = types1<any>; type type11 = types1<unknown>; 复制代码
5.11 条件类型
示例:T extends U ? X : Y
//普通的用法
type types2<T> = T extends string ? string : number;
//使用关键字的用法
type Type14<T> = T extends Array<infer U> ? U : T;
条件类型的 一些内置的方法:Exclude
,Extract
,NonNullable
,ReturnType
。
- Exclude<T,U> 获取U中不在T中的一项
type Type15 = Exclude<"a" | "b" | "c", "a" | "b">;
- Extract <T,U> 获取T和U的交集
type Type16 = Extract<"a" | "b" | "c", "a" | "v">;
- NonNullable 去掉null 和undefined
type Type17 = NonNullable<string | number | null | undefined>;
- ReturnType 获取返回值类型
type Type18 = ReturnType<() => string>;