变量类型固定明确,不再像以往的JS数值随意赋值,动态类型
以JS为基础,在其基础之上构建TS,是它的一个超集,动态语言=>静态语言 let a:string = "q"
Type,类型 提高可维护性
【注】TS不能被JS解析器(浏览器)直接执行,需要编译为JS,最终执行还是JS
基本类型
1. 类型声明(值限制)
- 通过类型声明可以指定TS变量中变量(参数)的类型
- let 变量:类型 = 值
- let 变量 = 值 则类型由值确定 函数的参数不行,写默认值也可以fn(a = 1) a相当声明了number的类型
- 函数参数需要声明变量类型 fn():number{ }返回值也可以限制类型
【注】TS=>JS可以编译为任意版本的JS文件,默认ES3
2. 字面量声明类型
let a:10;//let a = 10 赋值一次就不能修改有点类似const 一般不用
let a:"A"|"B"//a只有两个取值
let a: boolean | string;//联合类型 要么布尔要么字符串
let a: number & string;//且,但是错误的,一般是多对象的交集
//any类型的变量可以赋值给任意类型的变量
3. any
let a: any//let a 一样 即声明变量不声明类型,则为any(隐式)
//a可以任意赋值,相当于关闭TS的该变量类型检查,不建议使用
4.unknown
let e: unknown //未知类型 类型安全 的any
e = 10;
e = "A";
//unknown类型的变量 无法直接赋值 给其他变量,除非 转类型
if(typeof e === "string"){
s = e;
}
//类型断言
//变量 as 类型 | <类型>变量
s = e as string//确定其类型
s = <string>e
5. void
//undefined 空值
function fn1 (msg = 1) : void{
};//没有返回值
6. never
//没有值 永远不会返回结果,有点类型null ,什么也没有,虚无
function fn() :never{
throw new Error("报错");
}//调用直接报错,什么返回也没有,空值都没
7. object
//对象结构限制
let b: {name: string}//声明一个对象且内部含有 name 属性 属性写死了
let b: {name?: string,age?: number}//加上?表示该属性可选
let b: {name: string,[propName: string]: any}//只有name有要求,其他属性不做要求可有可无
//函数结构限制
let d: (a: number,b: number) => number;//该函数参数都是number,返回值也是number
d = function(n1: number,n2: number): number{
retuen n1+n2;
}
8.array
//string[] 表示字符串数组,里面只能是字符串
let a: string[]
let a: number[]//Array<number>
9.tuple
//元组 固定长度 数组
let h:[string,string]
10.enum
//枚举
enum Gender{
Male = 1,
Female = 0
}
let i: {name: string,gender: Gender};
i = {
name:"a",
gender:Gender.Male
}
console.log(i.gemder === Gender.Male)//true
11.类型别名
type myType = string;//myType代替string
type myType = {
name: string,
age: number
};
type myNmuber = 1 | 2 | 3
let k: myNumber
编译选项
自动编译文件
- tsc xxx -w
- 每次更改ts文件都会自动编译,有点类似之前的nodemon
- 每个文件都需要单独监视
通过创建tsconfig.json文件,对编译进行预配置,然后运行tsc,可以对所有.ts文件合并编译,且tsc -w是对所有文件监听
-
include
-
//定义希望 被被编译文件 所在 目录 //默认值["**/*"] **任意目录 *任意文件 //例子 "include":["./src/**/*","./tests/**/*"] //所有src和test是目录下的文件都会被编译
-
-
exclude
-
//排除不希望被编译的文件所在 目录 //默认值["node_modules","bower_components","jspm_packages"] //例子 "exclude":["./src/hello/**/*"] //hello目录下的所有文件都不会被编译
-
-
extends
-
//定义被继承的配置文件 //例子 "extends":"./config/base" //即当前配置文件会自动包含base.json中的所有配置信息
-
-
files
-
//指定 被编译文件 的 列表,只有需要编译的文件少时才会用到 //例子 "file":[ "a1.ts", "b1.ts" ] //针对单个被编译文件
-
-
compilerOptions
-
//该配置存在许多子选项配置,用来完成对编译的配置 //target ts被编译为es的版本 //module 指定要使用的模块化规范 commonjs ES6 ... //lib 指定项目中要使用的库 一般不用 //outDir js文件的输出目录 //outFile 代码合并为一个文件 //allowJs 是否对js文件编译 //checkJs 是否检查js代码是否符合ts语法规范 默认false //removeComments 是否移除注释 //noEmit 不生产编译后文件 默认false //noEmitOnError 有错时 不生产编译后文件 比如不符合TS语法规范,直接不输出 //strict 所有严格检查总开关 //alwaysStrict 严格模式 //noImplicitAny 为声明变量类型默认为any 默认false,true为不允许隐式any会提示 //noImplicitThis 不允许隐式this //strictNullChecks 检查是否存在 { "compilerOptions": { "target": "ES6",//对应版本 "module":"ES6", "lib":["dom"], "outDir":"./dist", "outFile":"./dist/app.js",// 全局作用域 中代码合并 模块合并需要module:"amd"|"system" 一般用webpack模块打包 "allowJs":true,//可以通过该方法转js文件的es版本 只能高转低 } }
-
面向对象
一切操作都需要通过对象去完成,具体事物在程序中的抽象表示即对象
浏览器=>window
页面=>document
控制台=>console
在程序中所有的 对象 分成了两个部分 属性和方法 ,例如人有自己的名字、性别这些是数据,人可以说话、跑步这些是功能。
数据在对象中代表属性,功能在对象中代表方法。
1.类(class)
class 类名 {
属性名:类型//类型声明
//static 静态属性 不需要创建对象 就能访问
//static name:string = "a" 类名.name
//实例属性,需要 创建实例对象 才能访问
// name:stirng = "a" a = new 类名()a.name
//只读属性 无法更改值 readonly name:string = "a"
//可以结合static readonly
constructor(参数:类型){//构造函数
this.属性名 = 参数
}
方法名(){//也有static 变为类方法 可以直接调用不需要构建实例对象调用
...
}
}
2.抽象类
不希望使用超类创建实例对象
abstract class 类 {
//该类不能创建对象
//专门用来继承,作为父类
//抽象类中可以定义抽象方法
//没有方法体,子类必须对其重写
abstract fn():void
}
3.接口
//描述一个对象的类型
type myType = {//生成对象的属性限制
name: string,
age: number
}//不能重复声明 myType
/*接口 用来定义一个 类结构 包含哪些属性和方法,所有属实不能有实际值*/
//接口就是对类的一个 限制!
interface myInterface{
name: stirng;//注意分号
age: number;
}//可以重复使用同一接口,内容合并
interface myInterface{
gender: string;
}
//别名用法
const obj: myInterface = {
name: "s",
age: 2,
gender:"male"
}
//接口定义类,实现接口
class MyClass implements myInterface{
name: stirng;
age: number;
gender: string;
constructor(name:string,age:number,gender:string){
this.name = name
this.age = age
this.gender = gender
}
}
//语法糖写法
class MyClass implements myInterfence{
constructor(public name:string,public age:number,public gender:string){
}
}
4.属性的封装
避免实例对象的属性被任意更改,导致数据不安全
//属性修饰符
//public 修饰的属性可以在 任意位置 访问修改 默认
//private 当前类 的私有属性,继承类不能访问,只能在其内部进行修改,外部无法修改 TS独有,JS无所谓 一般加noEmitOnError:true直接无法编译
//通过在类中添加 方法暴露私有属性 可以被外部访问
getName(){//读取属性
return this.属性
}
setName(val:string){//可以通过该方法判断设置的数据是否符合规范,符合才设置
this.name = val
}
//属性存取器
//TS中设置getter方法的方式
get name(){
return tihs.name
}//实例对象.name直接调用该方法
set name(val:stirng){
this.name = val
}//实例对象.name = "aaaa"
//protected 在继承类中和超类中被访问,在外部不能被访问
5.泛型
定义函数或者类时,若类型不明确则使用泛型
function fn<T>(a:T):T{//T为泛型,不用any
return a
}
//直接调用
fn(10)//不指定类型,TS自动判断类型
fn<string>("aa")//指定类型,有点类似断言
//可以同时指定多个
function fn2<T,K>(a:T,b:K){
return a
console.log(b)
}
fn2<number,string>(10,"A")
//泛型T必须是Inter子类
interface Inter{
age: number;
}
function fn3<T extends Inter>(a:T):number{
return a.age
}
//类也可以指定泛型
class MyClass<T>{
name: T
constructor(name: T){
this.name = name
}
}
const m = new MyClass<string>("sss")