Typescript笔记
JS特点: 自由(不规范,不好维护)---》TS(规范,严格,类型系统,支持ES6)适合生命周期长,大型的项目
TS:严格定义类型。不推荐1.联合类型 2.any[]====Array<any>
内置对象类型
类型别名:用于定义类型
抽象类: 用于被继承,不能被实例化 eg: abstract class TestClass{}
类实现多个接口: 用于约束类
ts是一种工具,对于工具要体会他的思想(比如他是用来干嘛的?),api不重要
写代码时,可以先用伪代码把思路写出来,这样可以提高架构能力!然后再一步步依据伪代码的思路实现
TS是工具,体会其思想,不必记api,用的时候查就好
疑问: 为什么props,state要定义在那? 为什么事件对象的类型是那样的?那种泛型是什么意思?
=========================================================================================================
typescript未理解透的点:
枚举
ts使用思想: 1.先写实现再写接口 2.对外的实现才需要写接口,比如某些库不对外使用的api可以不用写接口,非公用的接口可以不抽离到types.ts文件
Request.onerror/ontimeout
继承内置对象时需要设置 Object.setPrototypeOf(this,SubClass.prototype)
导出类型文件:
Export * from ./types
类静态部分与实例部分的区别
当你操作类和接口的时候,你要知道类是具有两个类型的:静态部分的类型和实例的类型。 你会注意到,当你用构造器签名去定义一个接口并试图定义一个类去实现这个接口时会得到一个错误:
```typescript interface ClockConstructor { new (hour: number, minute: number) }
// error class Clock implements ClockConstructor { currentTime: Date constructor(h: number, m: number) { } } ```
这里因为当一个类实现了一个接口时,只对其实例部分进行类型检查。constructor
存在于类的静态部分,所以不在检查的范围内。
类型保护:类型谓词, typeof,instance of, 自定义类型保护
extend继承:本质上就是复制属性,且不覆盖原有属性
联合类型:|
交叉类型:&
!类型断言: Name! 表示告诉编译器name不为null
Tsc test.ts —strictNullChecks
编译到指定版本的js: tsc test.ts --target es5
类静态属性的使用
this的使用!
对于原生的xhr请求,如果请求内容为普通object时,需要json.stringify转化
请求内容需要与content-type一致:对象的content-type需要是application/json ,否则后端拿不到数据。
删除对象属性: delete obj[prop]
类实现接口的时候,是实现的实例部分,而非构造器部分
构造器接口的使用:
Never :表示函数不可返回:如会发生异常,或无限循环
局部变量和箭头函数可以不申明类型。
可索引的类型: 接口可以描述那些能够通过索引得到的类型,可索引类型具有一个索引签名,它描述了对象索引的类型,还有相应的索引值类型,
索引签名支持两种类型:number 和 string,但是由于 number 实际上会被转化为 string 类型(根据对象 key 的性质),所以需要遵守:number 索引的返回值类型是 string 索引的返回值类型的子类型。
eg:
interface IPerson {
[index: string]: string;
}
let me: IPerson = {love: 'TS'}
me.name = 'funlee';
me.age = 18; // error
interface Counter{
声明文件: 即类型定义文件,用于定义类型约束
pasting
泛型: 参数化的类型,一般用于限制集合内容。 eg: Array<string>
构造函数: 不可在外部调用,只有实例化的时候被调用,且只调用一次。
genrator函数: 1.yield相当于断点 2. generator()时不会执行任何函数内代码,.next()才会执行。
// type extends type (类型继承类型?)
type Nametype = {
name: string;
}
type UserType = Nametype & { age: number };
const valueType: UserType = { name: 'zyb', age: 23 };
拆分字符串:
自定义类型: class Person {}
pasting
有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements
关键字来实现。这个特性大大提高了面向对象的灵活性。
接口可以继承接口,也可以继承类,
类无法继承接口
enum Directions {
declare
declare
定义的类型只会用于编译时的检查,编译结果中会被删除。
类型别名与字符串字面量类型都是使用 type
进行定义。
-
存取器(getter & setter):用以改变属性的读取和赋值行为
-
修饰符(Modifiers):修饰符是一些关键字,用于限定成员或类型的性质。比如
public
,protected,private,
static,readonly,abstract -
抽象类(Abstract Class):1.抽象类是供其他类继承的基类,抽象类不允许被实例化。2.类中的抽象方法必须在子类中被实现
-
接口(Interfaces):不同类之间公有的属性或方法,可以抽象成一个接口。接口可以被类实现(implements)。一个类只能继承自另一个类,但是可以实现多个接口
当且仅当在以下几个场景下,我们才需要使用三斜线指令替代 import
:
-
当我们在书写一个全局变量的声明文件时(在全局变量的声明文件中,是不允许出现
import
,export
关键字的。一旦出现了,那么他就会被视为一个 npm 包或 UMD 库,就不再是全局变量的声明文件了。) -
当我们需要依赖一个全局变量的声明文件时(全局变量的类型,它们是没有办法通过
import
来导入的)
三斜线指令必须放在文件的最顶端,三斜线指令的前面只允许出现单行或多行注释。如下:
/// <reference types="jquery" />
使用全局变量的声明文件时,如果是以 npm install @types/xxx --save-dev 安装的,则不需要任何配置。如果是将声明文件直接存放于当前项目中,则建议和其他源码一起放到 src 目录下(或者对应的源码目录下):
/path/to/project
如果没有生效,可以检查下 tsconfig.json
中的 files
、include
和 exclude
配置,确保其包含了 jQuery.d.ts
文件。
需要注意的是,声明语句中只能定义类型,切勿在声明语句中定义具体的实现
在 TypeScript 中,boolean
是 JavaScript 中的基本类型,而 Boolean
是 JavaScript 中的构造函数。其他基本类型(除了 null
和 undefined
)一样,不再赘述。
可选参数后面不允许再出现必需参数了:
Initializer:初始设定式即=等号
类型断言的用法:在需要断言的变量前加上 <Type>
或 后面加上as TYPE 或者 变量后加!如:test!
类型断言不是类型转换,断言成一个联合类型中不存在的类型是不允许的
当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能
通常我们会把声明语句放到一个单独的文件(jQuery.d.ts
)中,这就是声明文件
当let声明出现在循环体里时拥有完全不同的行为。 不仅是在循环里引入了一个新的变量环境,而是针对 每次迭代都会创建这样一个新作用域。 这就是我们在使用立即执行的函数表达式时做的事,所以在 setTimeout例子里我们仅使用let声明就可以了。
for (let i = 0; i < 10 ; i++) {
setTimeout(function() {console.log(i); }, 100 * i);
}
会输出与预料一致的结果:0-9
重载:
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
上例中,我们重复定义了多次函数 reverse
,前几次都是函数定义,最后一次是函数实现。
注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
疑问:枚举
null
和undefined
是所有类型的子类型。 就是说你可以把 null
和undefined
赋值给number
类型的变量,如下:
never
类型是任何类型的子类型,也可以赋值给任何类型(试了不可以,同上);然而,没有类型是never
的子类型或可以赋值给never
类型(除了never
本身之外)。 即使 any
也不可以赋值给never
。
any
类型是十分有用的,它允许你在编译时可选择地包含或移除类型检查。 你可能认为 Object
有相似的作用,就像它在其它语言中那样。 但是 Object
类型的变量只是允许你给它赋任意值 - 但是却不能够在它上面调用任意的方法,即便它真的有这些方法:
类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript会假设你,程序员,已经进行了必须的检查。
TypeScript具有ReadonlyArray<T>
类型,它与Array<T>
相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:
leta:
number[] = [
1,
2,
3,
4];
letro: ReadonlyArray<
number> = a;
ro[
0] =
12;
// error!
ro.push(
5);
// error!
ro.length =
100;
// error!
a = ro;
// error!
上面代码的最后一行,可以看到就算把整个ReadonlyArray
赋值到一个普通数组也是不可以的。 但是你可以用类型断言重写:
a = ro
asnumber
[];
对象字面量会被特殊对待而且会经过 额外属性检查,当将它们赋值给变量或作为参数传递的时候。 如果一个对象字面量存在任何“目标类型”不包含的属性时,你会得到一个错误。
一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
赋值的时候,变量的形状必须和接口的形状保持一致(属性不能多也不能少)。
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
如上的NumberArray
表示:只要索引的类型是数字时,那么值的类型必须是数字
注解:对程序元素的说明,用于告诉工具和框架如何处理该程序元素。(注解具体有什么用?)
类型定义文件(*.d.ts):帮助开发者在typescript中使用已有的js工具包(jquery)(如何帮助,具体有何用?)
两种使用方式:
1.找类型定义文件:
https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types
然后下载后,copy到项目文件夹
2.或者直接安装类型定义文件:
https://github.com/typings/typings
泛型: 用于限制集合的内容
接口: 用于约束属性和方法
interface和implements关键字
类的继承: extends
构造函数:实例化的时候执行,且只执行一次。子类的constructor中,必须用super()调用父类的constructor
访问控制符: public,private(内部才可访问),pretected(内部和子类可访问)。 默认是public
TypeScript是一种由微软开发的支持ES6标准的编程语言,它是Angular2的开发语言。它可以编译成纯JavaScript,可以在任何浏览器,任何计算机和任何操作系统上运行,并且是开源的。
js的超集
而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。
TypeScript扩展了JavaScript的语法,所以任何现有的JavaScript程序可以不加改变的在TypeScript下工作。
TypeScript是为大型应用之开发而设计
js 支持es5
ts 支持es6
ts开发环境-compiler-浏览器不支持es6-在线compiler(官网playground)
开发环境:
一. 命令行方式:
1. npm install -g typescript 2. Tsc test.ts
二. IDE方式:
1.webstorm自带编译功能
2. Vscode 需要配置,配置方法自己搜!
字符串: 1.多行字符串 2.字符串模板 3.自动拆分字符串
类型定义:
1. 几种基本类型
2. 自定义类型
参数: 1.参数类型;2参数默认值;3.可选参数(1.记得可选参数没传情况要做处理 2.可选参数只能在必选参数后面!)
默认参数: (name:string = ‘joe’)
可选参数: (age?: number)
函数新特性:
typescript暂时不支持如下对象展开符语法:
generator函数(typescript暂不支持):yield控制函数执行过程(yield:放弃 类似于return)
对象的析构赋值:
const {age:{age1}} = obj 等价于 const {age1} = obj.age
数组的解构赋值:
箭头函数: this指向函数定义的作用域中的this!
forEach不输出属性,也不支持break关键字
For in 可用于数组,会输出数组的属性
For of 可用于数组和字符串,不用于对象。不会输出数组属性值,支持break