TypeScript
类型基础
在强类型语言中,当一个对象从调用函数传递到被调用函数时,其类型必须与被调用函数中声明的类型兼容
强类型语言不允许改变变量的数据类型,除非进行强制类型转换
弱类型语言中,变量可以被赋予不同的数据类型
静态类型语言:在编译阶段确定所有变量的类型(如c++)
1. 对类型要求极其严格
2. 立即发现错误
3. 运行时性能较好
4. 自文档化
动态类型语言:在执行阶段确定所有变量的类型(如js)
1. 对类型非常宽松
2. Bug可能隐藏很久
3. 运行性能较差
4. 可读性差
注意:有人提出强类型语言在程序发生错误后不允许继续执行,但是c++并没有对数组越界进行处理,所以认为它是弱类型语言。(归属特殊定义).
强类型 |
注意:如果把ts当做一门语言看待,那么它是强类型还是弱类型,是静态类型还是动态类型
我认为是静态+强类型语言
ts基础
webpack 配置
webpack的配置写在build文件夹里,对应的去安装npm包,项目想要使用的包写在package.json文件中。
生产和开发环境对应的其实是webpack的不同配置文件。
打包对应的也是一个webpack的文件
- 项目启动不起来,报如下错误
errno: 'ENOTFOUND', |
刚开始怎么改配置文件都不对,后来仔细看了看提示,再网上搜了一下,发现是host绑定的不对,然后去看了下自己的host文件,果然,localhost绑定的并不是本地的。修改host即可正常启动。
- 安装包的时候如果没有指定版本安装就会报找不到包的错误
会报E404的问题,Not Found - GET http://r.cnpmjs.org/typecript - [not_found] document not found
,这个问题我还没有找到为什么,现在是通过安装指定版本的包来解决的。
有可能:
- 基于-D依赖安装,npm自动安装的版本没有对应的依赖,所以安装错误
基本类型
类型系统
类型注解
作用:相当于强类型语言中的类型声明
语法:(变量/函数):type
- 变量的基本类型定义之后就不可改变
联合类型
表示数组的类型既可以是number也可以是string类型。
let arr2: Array<number | string> = [1, 2, 3, '4']
元组
可以通过push方法为元组新增元素,但无法对越界元素进行访问。开发过程中不建议这样使用。
undefined && null
在ts文档中,undefined和null是任何类型的子类型可以被赋值给任意类型。可以通过设置tsconfig.json中的”strictNullChecks”: false来避免报错
void
void类型标识没有任何返回值的函数或方法
any类型
不标识类型,非特殊情况,不建议使用any类型。通过any类型实现对js的兼容
never
表示永远不会有返回值的类型,比如一个函数抛出了一个异常,还有死循环函数
枚举类型
一组有名字的常量集合,enum关键字。
数字枚举 && 字符串枚举
数字枚举的实现原理为反向映射。
但字符串枚举不是反向映射
异构枚举
当数字枚举和字符串枚举混合使用就形成了异构枚举,但是不建议这样做
枚举成员
枚举成员的值在定义后变为只读类型,在定义之后是不能修改的
const member
- 无初始值
- 对已有枚举成员的引用
- 常量表达式
// const member |
computed member
- 这些值会在程序执行的时候被赋值,而不是在编译阶段
d = Math.random(), |
在此状态下的,枚举成员必须需要初始值。
常量枚举
const enum Month { |
常量枚举会在编译阶段被移除。当我们不需要一个对象,但需要对象的值得时候可以使用常量枚举
接口
- 接口约束对象 函数 类的结构
- 对象的接口如何定义
- 关键字 interface
- 作用 :规范对象的属性 属性的类型 属性值的类型
- 类型断言 用as 或者<>的形式 ,后者在react中使用会出问题
- 可选属性 通过?来设置
- 只读属性 通过readonly 来设置
- 当不确定接口中属性个数时需要使用 索引签名
- 索引签名包括字符串索引签名和数字索引签名
- 当接口中定义了一个索引后,例如设置了 【x:string】= string,就不能设置y:number了。
因为设置了【x:string】= string相当于这个接口的字符串索引返回值都是字符串,而y:number违背这一原则,冲突了。反过来 如果定义了【x:string】=Number, 就不能设置 y:string了。 - 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。因为 数字索引或转化为字符串索引,而转化的这部分索引对应的值的类型范围 超过了 字符串索引类型的范围,就会报错,相当于超出范围
- 一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
泛型
类型推断
类型兼容性
当一个类型Y可以被赋值给另一个类型X时,我们就可以说类型X兼容类型Y。
X 兼容 Y:X(目标类型) = Y(源类型)
源类型必须具备目标类型的所有属性。
结构之间兼容:成员少的兼容成员多的
函数之间兼容:参数多的兼容参数少的
类型保护
typescript 能够在特定的区块中保证变量属于某种确定的类型,可以在此区块中放心的引用此类型的属性,或者调用此类型的方法。
类型保护方法:
- 使用instanceof 可以判断一个实例是不是属于某个类
- 使用in 可以判断一个属性是不是属于某个对象
- 使用 typeof 可以判断一个基本类型
- 类型保护函数:某些判断可能不是一条语句能够搞定的,需要更多复杂的逻辑,适合封装到一个函数内
高级类型:交叉类型和联合类型
ts为了保障语言的灵活性而引入的类型:交叉类型和联合类型
交叉类型是取所有类型的并集,使用 & 符。比较适合做类型的混入
联合类型使用 | 符,具有不确定性,可以增强代码的灵活性
可区分的联合类型:利用两个类型的共有属性建立类型保护区块。
高级类型:索引类型
keyof T
interface obj { |
T[K]
let value: Obj['a'] |
T extends U
|
索引类型可以实现对对象属性的查询和访问,再配合泛型约束就可以使我们建立对象、对象属性以及属性值之间的约束关系。
映射类型
从旧类型中创建新类型的一种方式。新的类型以相同的形式去转换旧的类型,比如可以令每个属性成为readonly或者可选的。
Readonly:只读
Partial:可选
条件类型
由条件表达式所决定的类型:T extends U ? X : Y
,含义是:如果类型T可以被赋值为U,那么结果类型就是X,否则就是Y。
工程篇
TypeScript 工具体系分为 babel系和非babel系
实战
- 定义组件继承:
class componentName extends Component<componentNameProps, componentNameState> {}
- 定义props 数据类型
- 定义state 数据类型