TypeScript重点
严格类型检查,开发时报错提示
问题
- js的函数是不考虑参数的类型和个数的
- 开发时,想让变量只存某一种类型的值
方案
3. js是弱类型的语言,使用TypeScript会做严格类型检查
4. 如果变量的声明和赋值是同时进行的,ts可以自动对变量进行类型检测
//会做类型检查
let a:string
a = "zhoudage"
console.log(a)
let b:number = 23
//如果变量的声明和赋值是同时进行的,ts可以自动对变量进行类型检测
//会自动给变量限制一个指定的类型
let c = "zhou"
c="hhh"
// js的函数是不考虑参数的类型和个数的
function sum(a:number,b:number):number{
return a+b
}
let res = sum(12,13)
console.log(res)
typescript有哪些类型,便于我们对变量进行限制
//可以直接使用字面量进行类型声明
//冒号后面是变量可取的值
let a:10
// a=23 报错
//可以使用 “|” 来连接多个类型 这里可以理解为sex可以取值的范围
let sex: "男"| "女"
console.log(sex) //undefined
sex = "男"
// sex = "1" 报错
console.log(sex)
//变量c可以取boolean和string两种类型
let c:boolean | string
c = true
c = "zhou"
// c = 2 报错
//此变量可以取任意类型 类似于原始js
let d:any//显示any
//声明变量如果不指定类型,则ts解析器会自动判断变量类型为any
let e//隐式 any
e = 34
e = "zhoudage"
d = 10
d="998"
d = true
let my:unknown
my = 23
my = "maio"
my = []
//undefined和any的区别
let s :string
//d为any类型,可以赋值为任意变量,但unknown不可以
//unknown类型的变量不能直接赋值给其它变量 是类型安全的any,比any用的多
s = d
// s =my 报错
// s = my若真要使用 使用断言:告诉编译器,我认为检查了,它就是这种类型
// s = <string> my
s = my as string
console.log(s)
//void 用来表示空,以函数为例,表示没有返回值的函数
function fn():void{
}
//表示永远不会返回结果
function fn2():never{
throw new Error("dage")
}
//object表示一个js对象 js的引用类型有对象、函数、数组
let o :Object
o = {}
o = []
// {属性名:类型,}限制对象里面写啥 ?代表可选项
let person :{name:string ,age?:number}
person={name:"xiaohong",age:12}
// person={name:"xiaohong",age:12,gender:"boy"} 报错
person={name:"xiaohong"}
//那如果对象里面的属性个数是变化的,如何限制呢
// 属性名为字符串 值为任意类型 【】代表可选也就是任意个数
let person1 :{name:string,[propName:string]:any}
person1 = {name:"dage",grade:6,degree:"998"}
/* 函数结构的限制*/
let func:(a:number,b:number)=>string
func=(a,b)=>{
return " "+a+b
}
// func(a:string,b:string)=>3 报错
/* 数组的类型声明*/
let arr:number[]
arr = [1,2]
// arr = ["1","2"] 报错
let g:Array<string>
g = ["1","3"]
// g = [1] 报错
//元组:固定长度的数组
let yuan:[string,number]
yuan = ["zhou",998]
// yuan = [1,2] error
/* enum 枚举 代替魔鬼数字,有一些英文的常量*/
enum Gender{
Male=1,
Female=0
}
let student:{name:string,gender:Gender}
student = {
name:"dage",
gender:Gender.Male
}
console.log("-------------",student.gender===Gender.Male)
/* 给类型起别名*/
//一个变量取值为一周的七天
type week = 1|2|3|4|5|6|7
let day:week
// 等价于 let day:1|2|3|4|5|6|7
day=3
// day = 9 error
ts文件编译常用命令
- tsc app.ts -w 监视ts文件实现自动编译,但只支持单个文件
- tsc 此命令需要tsconfig.json 才能生效
- 配置文件 tsconfig.json详解
{
// include用来指定哪些文件需要被编译
// src/** 代表src目录下的所有目录(任意目录) * 代表该目录下的所有文件(任意文件)
"include": [
"./src/**/*"
],
// 不包含的文件
"exclude": [
"./src/app.ts"
]
// 自动填上去的内容
/* "compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true
},
"exclude": [
"node_modules"
]*/
}
enum Gender{
Male,
Female
}
//接口可以类比ts里面的类型type
type person={
name:string,
age:number,
gender:Gender
}
//使用接口可以达到类似的效果
interface myPerson{
name:string,
age:number,
// gender:Gender
}
//多个接口:同名的接口会合并
interface myPerson{
gender:Gender
}
let p:myPerson
p = {
name:"dage",
age:12,
gender:Gender.Male
}
console.log(p)
//接口中属性不能有实际的值,接口中所有的方法都是抽象方法
interface myInter{
name:string
saybaba():void
}
//实现接口中的抽象方法和
class Demo implements myInter {
name: string
saybaba(): void {
console.log("baibai")
}
}
let d = new Demo()
d.saybaba()
ts属性地封装
背景
立即执行函数定义了一个类,但是实例的属性在外面可以随意更改,不安全,我们需要对属性进行封装
(function (){
class Person{
name:string
age:number
constructor(name:string,age:number) {
this.name = name
this.age = age
}
}
let p = new Person("zhou",12)
p.name = "hhh"
p.age = 120
console.log(p)
})()
方法一 使用private修饰符,加上get和set方法来保证安全
(function (){
class Person{
/*
public 修饰的属性可以在任意位置修改和访问 (默认值)
* privite 只能在类的里面修改和访问
* */
private name:string
private age:number
constructor(name:string,age:number) {
this.name = name
this.age = age
}
getName():string{
return this.name
}
setName(name:string):void{
this.name = name
}
}
let p = new Person("zhou",12)
console.log(p)
p.setName("dage")
console.log(p.getName())
})()
方法二 使用ts特殊的语法,也就是get和set的语法糖,更简洁
(function (){
class Person{
/*
public 修饰的属性可以在任意位置修改和访问 (默认值)
* privite 只能在类的里面修改和访问
* */
constructor(private _name:string, private _age:number) {
}
get name(){
return this._name
}
set name(val:string){
this._name = val
}
}
let p = new Person("zhou",12)
console.log(p)
console.log(p.name)
p.name = "miaomiao"
console.log(p.name)
})()
3种访问权限
public 修饰的属性可以在任意位置修改和访问 (默认值)
privite 只能在类的里面修改和访问
protect 只能在当前类和当前类的子类中访问
class A {
constructor(protected _name) {
}
}
class B extends A{
test(){
console.log(this._name)
}
}
let b = new B("dage")
b.test()
ts的泛型
当定义函数和类时,遇到类型不明确的时候,可以使用泛型
//定义一个函数,接受任意类型的参数,再返回这个任意类型的参数
function fnc<T>(a:T):T{
return a
}
//ts可以自动对类型进行推断
let a = fnc("123")
let b = fnc(12)
//可以在使用的时候直接指定泛型的类型 推荐这种方式
let c = fnc<boolean>(true)
function fn<T,R>(a:T,b:R):T{
console.log(b)
return a
}
a = fn<string,number>("xiang",12)
console.log(a)
class MyClass<T>{
name:T
constructor(name:T) {
this.name = name
}
}
let m = new MyClass<string>("hahh")
console.log(m.name)
interface Inter{
length:number
}
//表示泛型R必须是Inter的实现类 (子类)
function fn3<R extends Inter>(a:R):number{
return a.length
}
console.log(fn3("zhou"))