1.ts 静态类型

就是定义数据类型后,不可改变,还有深层级的理解,就是继承定义变量的属性及方法。

基础静态类型 冒号后跟数据类型 可以跟 number string null undefinde boolean void

// 对象类型 普通对象类型 数组类型 类类型 函数类型
const guan:{
name:string,
age:number
} = {
name:'关关',
age:19
}
const guan2 :string [] = ['谢大脚','刘英'] // 定义数组类型,里面是字符串类型
class Preson{}
const guan3 :Preson = new Preson()
const guan4 :()=>string = ()=>{return '广告'}
2.ts 类型注解和类型推断
类型注解 
let count : number
cont = 123 // 鼠标放上 会有提示 nmuber 类型
类型注解
const one = 1
const two = 2
const three = one + two // 鼠标放上 自动推断出 three 是 number 类型
function getTotal(one,two) {
    return one + two
}
const total = getTotal(1,2) // 这时鼠标放到 total 上 显示 any 则推断不出来返回是什么类型 
function getTotal(one:number,two:number) {
    return one + two
}
const total = getTotal(1,2) //这时鼠标放到 total 上 显示number
可以判断出 对象中常量的类型
const guan5 = {
    name:'guanguan',
    age:18
} // 鼠标放到 Guana5 上会显示 name : string age:number
3.初识 interface
因为 interface 这个概念在js中并没有,所以 interface 编译后并不会呈现到 js 中,只会进行静态的类型检查。
// 没用之前
const getFn = (name:string,age:number,bust:number)=>{
    console.log('姓名:', name);
    
}
getFn('12',2,2)

// 用interface
interface Girl {
    name:string;
    age:number;
    bust:number
}
const girl = {
    name:'关关',
    age:12,
    bust:90
}
const getFn = (girl:Girl)=>{
    console.log('姓名:', girl.name);
    
}
getFn(girl)

会发现相同得传值地方很多,需要每次去写,不优雅,代码繁琐。你就会问和  类型别名 type ,其实是一样得就一点 不同,type 是直接可以赋值得,但是 interface 传递就必须是一个对象。

type Girl1 = string

想要传递更多参数,但是又不是必填字段,该怎么写?在后面添加一个问号
interface Girl {
    name:string;
    age:number;
    bust:number;
    like?:string;
}
const girl = {
    name:'关关',
    age:12,
    bust:90,
    like:'帅哥'
}
const getFn = (girl:Girl)=>{
    console.log('喜欢:',girl.like);
    
}
getFn(girl)

如果 like 后面没有跟 ?console.log(girl.like) 报错了。

这个时候你又应该问了,几个参数还可以写,要是很多参数怎么办,总不能一个一个写吧 ,哈哈。ts 也帮我们解决了,如下 [propname:string] 代表属性名是字符串类型,他得值是 any 任何类型。

interface Girl {
    name:string;
    age:number;
    bust:number;
    like?:string;
    [propname:string]:any
}
const girl = {
    name:'关关',
    age:12,
    bust:90,
    like:'帅哥',
    sex: '女',
    eat:'苹果'
}
const getFn = (girl:Girl)=>{
    console.log('喜欢:',girl);
    
}
getFn(girl)
给 Girl 添加一个说话得方法
interface Girl {
    name:string;
    age:number;
    bust:number;
    like?:string;
    [propname:string]:any;
    say():string
}
const girl = {
    name:'关关',
    age:12,
    bust:90,
    like:'帅哥',
    sex: '女',
    eat:'苹果',
    say:(()=>{return '123'})
}
const getFn = (girl:Girl)=>{
    console.log('喜欢:',girl.say());
    
}
getFn(girl)
extends与implements的不同

1.在类得声明中,通过关键字 extends 来创建一个类得子类。一个类通过 implements 声明自己使用一个或者多个接口。

2.extends 是继承某个类,继承之后可以使用父类得方法,也可以重写父类得方法。

implements  是实现多个接口,接口得方法一般为空,必须重写才能使用
3.extends 是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承
interface Girl {
    name: string;
    age: number;
    bust: number;
    like?: string;
    [propname: string]: any;
    say(): string
}
interface Teacher extends Girl {
    teach(): string
}
class Preson implements Girl {
    name = '111'
    age = 12
    bust = 90
    say() {
        return '欢迎光临'
    }
}
const girl = {
    name: '关关',
    age: 12,
    bust: 90,
    like: '帅哥',
    sex: '女',
    eat: '苹果',

    say: (() => { return '123' }),
    teach: (() => {
        return 'jdijisodsids'
    })
}
const getFn = (girl: Teacher) => {
    console.log('喜欢:', girl.teach());

}
getFn(girl)
4.类的使用
class Lady {
    content = 'hi 你好啊'
    sayHello() {
        return this.content
    }
}
class Gril extends Lady{
    content = "不开心",
      sayHello() {
        return super.sayHello() + '111' // 使用父类中sayHello 方法
    }
}
let LadyClass = new Gril()
console.log(LadyClass.sayHello()); // 不开心
console.log(LadyClass.content);  // 不开心
5.类的访问

private 私有的  不能在外部及继承中使用,代码提示会报错,无法使用

protected  保护的   能在内部使用,不能在外部使用  但是在继承中是可以使用的

pulbic 公有的 在内部和外部都是可以调用的

类的内部和外部 {}外是外部 {}内是内部

class Person {
    public name: string | undefined;
    protected say(){
       console.log(this.name + '你好啊');
        return this.name + '你好啊'
        
    }
}
const person = new Person()
person.name = 'jsGuan'
person.say()
console.log(person.say());
name 如果不写就是默认为 public 所以在内部,外部是能访问的 person.name x现在把 say 方法写 protected 就会发现在外部是调用 say 方法是有访问不到的。
6.类的构造函数
在 new 出对象后自动执行
class Person {
    public name : string | undefined
    constructor(name:string){
        this.name = name
    }
}
const person = new Person('guanguan')
console.log(person.name); // guanguan
// 简便写法
class Person {
    constructor( public name:string){
    }
}
// 继承 子类只有是构造函数 constructor 就必须调用super() 方法
class Person {
    constructor( public name:string){
    }
}
class Son extends Person{
    constructor(public age:number) {
        super('jingjing')
    }
}
const son = new Son(12)
console.log(son.name); // jingjing
console.log(son.age); //12
7.类的Getter setter static
class xiaoJieJie {
    constructor(private _age:number){ }
    get age () {
        return this._age
    }
}
const mom = new xiaoJieJie(18)
console.log(mom.age);
比如小姐姐类的年龄,不想让外界知道,所以 用 private 保护起来,通过 get 方式 renturn 出去。可以在 get 方法里面做一些操作封装一下等等。先执行 set 在执行 get
class xiaoJieJie {
    constructor(private _age:number){ }
    get age () {
        console.log(2);
        return this._age + 1
    }
    set age (age:number) {
        console.log(1);
        this._age = age + 10
    }
    
}
const mom = new xiaoJieJie(18)
mom.age = 20
console.log(mom.age); // 31

补充一个 静态类的方法

不需要在实例化 一个对象 进行调用,直接用 class.方法属性

class Girl {
  static  sayLove() {
        return 'I love you'
    }
}
console.log(Girl.sayLove());
只读属性 readonly 
class Person {
    public readonly _name :string
    constructor(name:string) {
            this._name = name
    }
}
const person =  new Person('guanguan')
person._name = 'jingjing' // 报错  因为 _name 属性是只读属性
console.log(person._name);

8.抽象类

概念:和父类很像都需要继承,抽象类一般都有一个抽象方法,继承抽象类的类,必须实现抽象方法才可以

关键字 abstract
// 每一个类都需要一个技能 但是 每一个类里面 他们的技能是不同的 可以用抽象类
abstract class Girl {
    abstract skill():any // 没有大括号,因为每一个类的方法是不同的,所以不同写上
    abstract say() :any
}
class waiter extends Girl {
    skill() {
        // 实际操作逻辑
        console.log(1);
        
    }
    say() {
        console.log(2);
        
    }
}
class Baseteacher extends Girl {
    skill() {
        console.log(3);
    }
    say() {
        console.log(4);
    }
}
9.联合类型和类型保护(也叫类型守护)
只有参数有或者有2种以上这种方法就叫做联合类型
interface son {
    anjiao:boolean;
    say: ()=>{
        la:string
        age:number
        
    }
}
interface teacher {
    anjiao:boolean;
    sayBey: ()=>{
        la:string
        age:number
        
    }
}
function whatHow(animal:son | teacher) {

}

animal.say() 发现会报错。因为你不知道这个 say() 方法是谁的,所以这个时候就会用到类型守护。

类型保护 
1.类型断言 as 方式  

2.in 方式

3.typeof

4.instanceof

as 方式  (animal as teacher).sayBay()
interface son {
    anjiao:boolean;

}
interface teacher {
    anjiao:boolean;
    sayBay: (()=>{})
}
function whatHow(animal:son | teacher) {
   if (animal.anjiao) {
        (animal as son).anjiao
        console.log(animal.anjiao); 
        
   } else {
    (animal as teacher).sayBay()
    console.log( (animal as teacher).sayBay()); // 'wowowo'
   }
}
const Girl = {
    anjiao:false,
    sayBay(){
       return 'wowowo'
    }

}
whatHow(Girl)
in 方式  ('skill' in type)
interface son {
    anjiao:boolean;
    skill :(()=>{})

}
interface teacher {
    anjiao:boolean;
    sayBay: (()=>{})
}
const Girl = {
    anjiao:false,
    sayBay(){
       return 'wo shi saybay'
    }

}
function towho(type:son | teacher) {
    if ('skill' in type) {
        type.skill()
        console.log( type.skill());
        
    } else {
        type.sayBay()
        console.log( type.sayBay()); // 'wo shi saybay'
    }
}
towho(Girl)
typeof 方式
function add(frist: number | string, second: number | string) {
    if (typeof frist === "string" || typeof second === "string") {
        return `${frist}${second}`

    }
    return frist + second
}
10.tyepscript 命名空间 namespace

1.新建一个文件夹 放到 vscode 中 ,然后打开终端,允许 npm init -y 创建 package.json 文件。

2.生成文件后,我们直接在终端允许 tsc -init ,生成 tsconfig.json

3.新建 src 和 build 文件夹,在创建一个 index.html

4.在 src 目录下,新建 一个 page.ts 文件,开始要编写 ts 文件了。

5.在配置 tsconfig.json 文件,设置 outDir 和 rootDir, 也就是设置需要编译的文件目录,和编译好的文件目录。

6.然后编写 index.html,引入,当让我们现在还没有 page.js 文件

7.编写page.ts文件,加入一句输出console.log('你好 关关'),再在控制台输入tsc,就会生成page.js文件

8.再到浏览器中查看 index.html 文件,如果按F12可以看到你好 关关,说明我们的搭建正常了。


看到上面还是没有使用命名空间时,Top Contrnt Footer 都是全局变量,容易造成全局变量混乱,所以需要进行模块化的划分,这个时候就需要 进行命名空间,关键字时 namespace 写法在 page.ts 中注释那样进行编写。

这个语法,很类似编程中常说的模块化思想,比如webpack打包时,每个模块有自己的环境,不会污染其他模块,不会有全局变量产生。命名空间就跟这个很类似,注意这里是类似,而不是相同。

命名空间声明的关键词是namespace比如声明一个namespace Home,需要暴露出去的类,可以使用export关键词,这样只有暴漏出去的类是全局的,其他的不会再生成全局污染了

index.html  script 修改 

new Home.Page();


深入了解 命名空间,接近实战,命名空间组件化