什么是typescript?
typescpt是一种静态类型语言。
添加了类型的js,完全兼容js,写完后可以编译为js
我觉得是用另一种更为严格和规范的方式去写js
##静态类型语言
静态类型语言中,变量的类型必须先声明,即在创建的那一刻就已经确定好变量的类型,而后的使用中,你只能将这一指定类型的数据赋值给变量。如果强行将其他不相干类型的数据赋值给它,就会引发错误。
在静态语言中,一旦声明一个变量是int类型,之后就只能将int类型的数据赋值给它,否则就会引发错误,而动态类型则没有这样的限制,你将什么类型的数据赋值给变量,这个变量就是什么类型
强类型 VS 弱类型
强弱之分,体现在对类型的检查严格程度上,弱类型语言对于变量类型的检查比较宽松,容忍隐式类型转换这种事情的发生。何为隐式类型转换,一般有两种形式:
- 相关类型之间隐式转换
- 不相关类型之隐式间转换
一、基础类型
1. ts有哪些基础类型?
布尔、数字、字符串、数组、元祖、枚举、any、void、null、undefined、never、Object2. 定义数组:
1
2let arr: Array<number> = [1,2,3]
let arr2: number[] = [1,2,3]3. 定义元组:
注意:访问越界元素会报错1
let x: [string,number,string] = ['aaa',111,'aaa']
1
2
3x[3] = "world"; // Error, Property '3' does not exist on type '[string, number]'.
console.log(x[5].toString()); // Error, Property '5' does not exist on type '[string, number]'.4. 枚举:定义类型
1
2
3
4
5
6enum Color {
Red = '#ff0000',
Green = '#00ff00',
Blue = '#0000ff'
}
let color: Color = Color.red5. never
never是任何类型的子类型,可以复制给任何类型,但没有类型是never的子类型或可以赋值给never类型(除了never本身),即使是any也不能复制给never。
never经常用于抛出异常的函数,或是死循环。
变量也可以是never类型,当他永不为真的类型保护所约束时。
1 | let n: never |
6. void
void表示没有任何类型。和any完全相反。函数没有返回值时可以写void
1 | function warnUser(): void { |
void变量没有什么作用,因为void变量只能赋值null或undefined。
7. 类型断言
我可能有时候比ts更了解这个变量是什么类型,这时就可以用类型断言
语法有两种
第一种:尖括号
1 | let someValue: any = "this is a string"; |
第二种:as
1 | let someValue: any = "this is a string"; |
二、变量声明
ts用const、let代替了var
三、接口
1. 对象类型
定义一个类型,让变量按照这个类型来具体实现
1 | interface LabelType { |
1 | let labelObj: LabelType { |
2. 函数类型
1 | interface Square{ |
上面代码意思是,一个函数类型叫Square,它应该有两个参数,一个source类型string,一个subString类型string,返回boolean类型的值。
1 | let sq: Square = function(source: string,subString: string) { |
3. 类类型
1 | interface ClockInterface { |
接口亦可以继承
1 | interface Shape { |
四、类
1 | // 1. 基本使用class Person |
1 | class Animal { |
1. public、protected、private的区别:
protected:可以继承,不可以在类外部使用
private:不可以继承,不可以在类外部使用
public:可以继承,可以在类外部使用
2. readonly:
1 | class Person { |
3. getter、setter
1 | let passcode = "secret passcode"; |
4. 静态属性、静态方法
使用static定义,只能用类名.方法/属性使用
5. 抽象类与抽象方法
1 | abstract class Animal { |
6. 抽象类和接口的区别
(1)abstract类
abstract类是定义用来被继承的类。
抽象类中可以有抽象方法,可以有普通方法。非抽象类也可以。
但抽象类不能创建对象,普通类继承抽象类必须实现其方法,或将其定义为抽象方法。
抽象类必须在类前用abstract关键字修饰。
因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。
1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
2)抽象类不能用来创建对象;
3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
4)非抽象类中可以有抽象方法,比如继承的时候,如果子类不想实现父类的抽象方法,则必须将该方法也定义为抽象方法
(2) interface接口: 是对类的补充
接口中可以含有 变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final
变量(并且只能是public static final
变量,用private
修饰会报编译错误)
而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。
五、函数
1 | function add(a: number,b:number): number { |
六、泛型(尖括号)
1. 泛型变量
一个函数在公用的时候,若同一个参数可能有多个类型or可能有多种返回值的情况下,如果写成any会不严谨
1 | function identify(arg: any) : any { |
用下面这个就可以保证返回值与参数相同类型
1 | function identity<T,Y>(arg: T,arg2: Y): T { |
2. 泛型类、泛型接口
1 | class GenericNumber<T> { |
1 | interface Person<TT,YY> { |
七、枚举
1 | enum Color { |
八、高级类型
1. 类型别名
1 | type NameOrId = string | number |
2. 交叉类型
也就是用’&‘
1 | interface Person { |
3. 联合类型
也就是用’|’
let arg: number | string = ‘sfsdfds’
###4. 类型保护和类型断言
typeof和instanceof
(1)typeof
1 | type Name = string; |
(2)instanceof只对类有用。
1 | class A { |
九、Symbols
十、迭代器
for of 与for in
十一、模块(原:外部模块)
“内部模块”现在称做“命名空间”。 “外部模块”现在则简称为“模块”,这是为了与 ECMAScript 2015里的术语保持一致,(也就是说 module X {
相当于现在推荐的写法 namespace X {
)。
1 | import {ModuleA,ModuleB,ModuleC} from './module' |
用法和js一致。
十二、命名空间(原:内部模块)
“内部模块”现在称做“命名空间”。 “外部模块”现在则简称为“模块”,这是为了与 ECMAScript 2015里的术语保持一致,(也就是说 module X {
相当于现在推荐的写法 namespace X {
)。
1. 命名空间的基本用法
在一个文件中,有时候有些变量是不想定义为全局的,比如有ab两个类被c类引用,如果都定义为全局的变量,不好维护容易出错,可以只对外暴露出c类接口(export class C)给该文件其他部分使用。。
1 | namespace Home{ |
2. 复用
将逻辑与业务分离,可以将一个namespace用另一个namespace引入
如下面,用page引入components的命名空间
components.ts文件:
1 | namespace Components { |
page.ts文件:
1 | namespace Home{ |
由于这种写法很难搞懂命名空间是在哪个文件中,所以最好在path.ts头部中用三斜线指定进行指定
1 | /// <reference path="components.ts" /> |
###3. 子命名空间
1 | namespace Components { |
十三、三斜线指令
三斜线指令仅可放在包含它的文件的最顶端。放在其他地方则会被当做注释去解析的。
包括下面几个指令,去看官网吧
1 | /// <reference path="..." /> |
1 | /// <reference types="..." /> |
1 | /// <reference no-default-lib="true"/> |
1 | /// <amd-module /> |
tsc -w 监听,自动编译
tsc init 生成tsconfig.
tsconfig的配置:
outFile
outDir
module
rootDir
target
十四、声明文件
使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。
说人话:就是第三方库定义的一些东西直接引进来ts识别不了,ts只能识别js有的和ts已经定义的东西。所以需要另外写一份声明文件告诉ts,然后ts就知道这个第三方库有这些变量就不会报错了。
文件叫*.d.ts
declare 就是用在声明文件中的。
十五、项目配置
tsconfig.json