Typescript学习笔记

一.静态类型

在这里插入图片描述
在这里插入图片描述
一旦声明不可改变。
同时,声明类型的变量会继承所声明数据类型的方法
如下:count继承了number的方法
在这里插入图片描述
number是基础类型
除此之外还有

①对象类型

const xiaoJieJie: {
  name: string,
  age: number
} = {
  name: 'da',
  age: 18
}

②数组类型

const xiaoJieJies: string[] = ['12', '23', '34']
//上面这个例子必须传字符串数组

③类类型

class Person { };
const dajiao: Person = new Person();
// dajiao必须是一个Person的实例

④函数类型

const jianXiaoXiao: () => string = ()=>{return ''}
// jianXiaoXiao必须是一个函数并且返回值是一个字符串

二.类型注解和类型推断

1.类型注解

这句代码声明count是一个number类型的数据。这就是类型注解

let count: number = 1;

2.类型推断

在这里插入图片描述
在这里插入图片描述
  这里ts可以自动判断three的类型为number。
  这就是类型推断,根据已有类型对未知类型进行推断。

!!类型注解工作原则,ts能够自己推断的变量就不需要写类型注解,如果不能推断的就需要写类型注解。
在这里插入图片描述

像上面这种无法推断的就需要写类型注解
在这里插入图片描述
这种也不需要写
在这里插入图片描述

3.函数参数和返回类型的注解

在这里插入图片描述
有时候由于编写时的错误,可能导致变量在运行过程中类型被改变。如上面这种,程序并不会报错,所以需要对返回值进行注解。

function getTotal(one: number, two: number): number {
  return one + two ;
}

const total1 = getTotal(1, 2);

永远也执行不完的代码可用never注释
在这里插入图片描述
第一个是抛出异常,打印永远执行不到
第二个是一个无限循环函数
这两个都可以用never来注释

function add({one,two}:{one:number,two:number}){
  return one+two;
  
}
const totle8 = add({one:1,two:2})

在这里插入图片描述
当参数是一个对象时,需要以上面的方式写注释

4.数组类型注解

在这里插入图片描述
普通数组类型注解

1.类型别名

在这里插入图片描述
像上面这种对象定义可能很多地方都要重复使用如果每次都重复写{name:string,age:number}会相当繁琐。
可以使用类型别名,用变量保存
也可以使用类来定义
在这里插入图片描述

5.元组的使用和类型约束(使用得少)

const arr : (number | string)[] = [1,'sdfa',545]
//arr的注解允许定义number和string但是不会严格控制它的顺序 [1,'sdfa',545]或者 ['sdfa',1,'fdsf']都不会报错
const xiaojiejie: [string, string, number] = ["dajiao", "teacher", 28];
//如果想要严格控制顺序和类型需要使用元组,就像上面这样,第一个和第二个必须是string,第三个必须是number

三.接口

定义一个简单的接口,:前面写一个?就代表这个参数是可选的

interface Girl {
  name: string;
  age: number;
  face: number;
  waistline ?: number;
}

const girl={
  name:'xiaowang',
  age:18,
  face:'handsome',
  ll:1
}

const logInform = (girl:Girl)=>{
  console.log(girl);
  
}

1.用接口管理类

interface Girl {
  name: string;
  age: number;
  face: string;
  waistline ?: number;
  [propname:string]:any;
  // 有一些除上面的固定名字以外,我们可能还需要定义一些别的属性
  // 但是不想每个都定义一遍可以使用[propname:string]:any;
  // 它的意思就是属性名是字符串,内容可以是任意数据类型
  say():string;
  // 我们还可以指定一些函数,上面的say的意思是:有一个say()函数,它的返回值是string
}

class XiaoJieJie implements Girl{
  name='xiaowang'
  age=18
  face='handsome'
  say(){
    return 'hello world'
  }
}

2.接口的继承

interface Girl {
  name: string;
  age: number;
  face: string;
  waistline?: number;
  [propname: string]: any;
  // 有一些除上面的固定名字以外,我们可能还需要定义一些别的属性
  // 但是不想每个都定义一遍可以使用[propname:string]:any;
  // 它的意思就是属性名是字符串,内容可以是任意数据类型
  say(): string;
  // 我们还可以指定一些函数,上面的say的意思是:有一个say()函数,它的返回值是string
}
interface teacher extends Girl{
  teach():string;
}

teacher 接口除了有Girl的所有约束外,还有自身的teach函数约束。
也就是说使用teacher不仅要满足Girl的所有约束还要满足teacher的所有约束

四.类

子类的实例,既可以访问子类的属性和方法也可以访问父类的属性和方法

class Boy{
  sex='man'
  age=18
}

class studen extends Boy{
  study(){
    return 'I am learning!!'
  }
}

const xiaoming = new studen;
console.log(xiaoming.age);
console.log(xiaoming.study);

重写:在子类中定义与父类同名的属性或函数就叫重写。访问时会访问到子类的函数。也可以使用super在子类中调用父类的函数,处理成一个新的函数

class Boy{
  sex='man'
  age=18
  say(){
    return 'I am a boy'
  }
}
class studen extends Boy{
  say(){
    return super.say()+'hahaha'
  }
  study(){
    return 'I am learning!!'
  }
}

调用结果
在这里插入图片描述

1.类的访问类型

1.public 公共的(在类的内部和外部都可以访问)如果不写访问类型默认是public
2.private (只能在类的内部访问)
3.protected(只能在类的内部使用,可以在继承中的类使用)

class Animal{
  public age:number;
  private say(){
    return 'hou'
}//这个花括号内就是类的内部
  protected food:string;
}

class cat extends Animal{
  eat(){
    this.food
  }
}
const dog = new Animal();
console.log(dog.age);
console.log(dog.say());

访问私有属性会报错
在这里插入图片描述
访问protected

class Animal{
  public age:number;
  say(){
    return 'hou'
  }
  protected food:string='apple';
}

class cat extends Animal{
  eat(){
    return this.food
  }
}
const miao = new cat();
console.log(miao.eat());

2.类的构造函数

class Person {
  public name:string;
  constructor(name:string){
    this.name = name;
  }
}
const person = new Person('xiaowang')
 console.log(person.name);

等同于(简写)

class Person {
  constructor(public name:string){
    this.name = name;
  }
}
const person = new Person('xiaowang')
 console.log(person.name);

1.子类的构造函数

class Person {
  constructor(public name:string){
    this.name = name;
  }
}
class Teacher extends Person{
  constructor(public age:number){
    super('xiaownag');
    // 这里必须使用super调用父组件的构造函数,并传递name参数
  }
}
const teacher = new Teacher(18)
 console.log(teacher);

在这里插入图片描述

3.类的Getter,Setter,Static

1.Getter

直接访问私有属性_age会报错,但是可以使用get暴露属性,可用于类的封装

class XiaoJieJie{
  constructor(private _age:number){}
  get age(){
    return this._age;
  }
}
const dajiao = new XiaoJieJie(18)

console.log(dajiao.age+5);

2.Setter

可以对类的私有属性进行操作

class XiaoJieJie{
  constructor(private _age:number){}
  get age(){
    return this._age+5;
  }
  set age(age:number){
    this._age = age+3
  }
}
const dajiao = new XiaoJieJie(18)

console.log(dajiao.age);

在这里插入图片描述

3.Static

普通方法调用

class Girl {
  sayLove() {
    return 'i love you!';
  }
}
const girl = new Girl();
console.log(girl.sayLove());

  调用类中的方法需要new一个实例,通过实例进行方法的调用
  有时候我们希望不用new一个实例就能调用方法,这时候可以对方法进行静态化

class Girl {
  static sayLove() {
    return 'i love you!';
  }
}
console.log(Girl.sayLove());

4.抽象类和只读属性

1.只读属性

class Person{
  constructor(public name:string){}

}
const person = new Person('xiaowang');
person.name='xiaohuang';
console.log(person.name);

在这里插入图片描述
实例被创建之后,还是可以修改属性。如果不希望属性在实例创建之后被修改,可以使用只读属性。

class Person {
  public readonly _name: string;
  constructor(name: string) {
    this._name = name;
  }

}
const person = new Person('xiaowang');
person._name = 'xiaohuang';
console.log(person._name);

这样就会报错
在这里插入图片描述

2.抽象类

用abstract 定义抽象类和抽象方法。
所有继承抽象类的类都要实现抽象类的抽象方法。

abstract class Girl1{
  abstract skill();
  // 定义一个抽象方法
}

class Waiter extends Girl1{
  skill(){
    console.log('喝水');
    // 所有继承抽象类的类都要实现抽象类的抽象方法
  }
}
class BaseTeacher extends Girl{
  skill(){
    console.log('按摩');
  }
}

五.tsconfig.json配置文件

在这里插入图片描述
“removeComments”: true,配置项设置ts编译成js后是否移除注释。
tsc
调用tsc命令会走tsconfig.json配置文件,如果写tsc tsc Dome.ts配置文件不会生效

"include":["Dome.ts"],

选择性生成js文件,数组内的文件会生成js文件,不在数组内的同一目录下的其他文件不会生成js文件。

"exclude":["Dome.ts"],

相对应的有exclude,除了数组里的文件,其他的都生成js文件。

"files":["Dome.ts"],

files和include差不多

1.compilerOptions

 "strict": true,                           /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    允许注解类型any不用特意声明
    // "strictNullChecks": true,              /* Enable strict null checks. */
    设置为false 允许null值出现
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

是否严格类型检查,如果开启则下面所有配置项为true不能配置。

// "strictNullChecks": true,              /* Enable strict null checks. */
const person:string = null ;

outDir是编译好的js的目录
rootDir是入口目录就是,ts文件的目录

 // "outDir": "./",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */

在这里插入图片描述
项目的目录结构一般是这样src放ts文件,build里放编译后的js文件。

 // "sourceMap": true,                     /* Generates corresponding '.map' file. */

生成,文件和编译后的文件的一个对应关系,排查错误会用到。

// "noUnusedLocals": true,                /* Report errors on unused locals. */
没有用到的变量会提示
// "noUnusedParameters": true,            /* Report errors on unused parameters. */
没有用到的方法会提示

六.联合类型和类型守护(类型保护)

interface Waiter {
  skill: boolean;
  say: () => {}
}
interface Teacher {
  skill: boolean;
  teach: () => {}
}
// 不止一种的就叫;联合类型
function jj(animal: Waiter | Teacher) {
  animal.say()
}

在这里插入图片描述
  当一个变量有一个以上的类型就是联合类型。访问其中一个类型的方法时就会报错,这时候需要用到类型保护。

1.类型断言

interface Waiter {
  name: boolean;
  say: () => {}
}
interface Teacher {
  skill: boolean;
  teach: () => {}
}
// 不止一种的就叫;联合类型
function jj(animal: Waiter | Teacher) {
  if(animal.name){
    (animal as Waiter).say()
  }else{
    (animal as Teacher).teach()
  }
  
}
function kk(animal: Waiter | Teacher) {
  if('say' in animal){
    (animal as Waiter).say();
  }else{
    (animal as Teacher).teach();
  }
}

案例:
在这里插入图片描述
在这里插入图片描述
instanceof只能用在类上

在这里插入图片描述

七.Enum枚举类型

enum Status{
  MASSAGE,
  SPA,
  DATA,
}
console.log(Status.MASSAGE);
console.log(Status.SPA);
console.log(Status.DATA);

在这里插入图片描述

enum Status{
  MASSAGE = 1,
  SPA,
  DATA,
}
console.log(Status.MASSAGE);
console.log(Status.SPA);
console.log(Status.DATA);

如果第一个赋值为1,则从1开始
在这里插入图片描述

enum Status{
  MASSAGE = 1,
  SPA,
  DATA,
}
console.log(Status.MASSAGE,Status[1]);
console.log(Status.SPA);
console.log(Status.DATA);

在这里插入图片描述
通过下标也可以访问值

八.泛型

1.在函数中使用泛型

在函数定义的时候<>里的名字可以随便起,然后使用的时候需要进行指定,就像下面这个例子。

function join<XiaoWang>(first: XiaoWang, second: XiaoWang) {
  return `${first}${second}`;
}
let s = join<string>("xiaowang", ' is a handsome boy');
console.log(s);

这个例子中定义了一个XiaoWang的泛型,名字可以随便起。使用的时候指定了string,所以first和second参数都是string类型。可以理解泛型就是一个指定类型的变量。

1.泛型中数组的使用

// 泛型中数组的使用
function myFun<ANY>(params: ANY[]) {
  return params;
}

myFun<string>(['123','456']);

等同于

// 泛型中数组的使用
function myFun<ANY>(params: Array<ANY>) {
  return params;
}

myFun<string>(['123','456']);

定义多个泛型

function join<T,P>(first: T, second: P) {
  return `${first}${second}`;
}
let s = join<string,Number>("xiaowang", 2);
console.log(s);

2.在类中使用泛型

一个简单的例子

class SelectGirl<T>{
  constructor(private girls: T[]) { }
  getGirl(index: number): T {
    return this.girls[index];
  }
}

const selectGirl = new SelectGirl<number>([1,8])
console.log(selectGirl.getGirl(1));

在这里插入图片描述
泛型的继承:

interface Girl {
  name: string;
}
class SelectGirl<T extends Girl>{
  constructor(private girls: T[]) { }
  getGirl(index: number): string {
    return this.girls[index].name;
  }
}
const selectGirl = new SelectGirl([
  {name:'xiaowang'},
  {name:'xiaohuang'},
  {name:'xiaoliu'}  
])

console.log(selectGirl.getGirl(1));

在这里插入图片描述
泛型的约束,泛型只能是number或string

九.命名空间

page.ts
只暴露出page类

namespace Home{
  class Header{
    constructor(){
      const elem = document.createElement('div');
      elem.innerText = 'this is header';
      document.body.appendChild(elem);
    }
  }
  class Content{
    constructor(){
      const elem = document.createElement('div');
      elem.innerText = 'this is Content';
      document.body.appendChild(elem);
    }
  }
  class Footer{
    constructor(){
      const elem = document.createElement('div');
      elem.innerText = 'this is Footer';
      document.body.appendChild(elem);
    }
  }
  
  export class Page{
    constructor(){
      new Header();
      new Content();
      new Footer();
    }
  }
}

page.js

"use strict";
var Home;
(function (Home) {
    var Header = /** @class */ (function () {
        function Header() {
            var elem = document.createElement('div');
            elem.innerText = 'this is header';
            document.body.appendChild(elem);
        }
        return Header;
    }());
    var Content = /** @class */ (function () {
        function Content() {
            var elem = document.createElement('div');
            elem.innerText = 'this is Content';
            document.body.appendChild(elem);
        }
        return Content;
    }());
    var Footer = /** @class */ (function () {
        function Footer() {
            var elem = document.createElement('div');
            elem.innerText = 'this is Footer';
            document.body.appendChild(elem);
        }
        return Footer;
    }());
    var Page = /** @class */ (function () {
        function Page() {
            new Header();
            new Content();
            new Footer();
        }
        return Page;
    }());
    Home.Page = Page;
})(Home || (Home = {}));

html
需要用命名空间的类名调用暴露出的类

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="./build/page.js"></script>
  <title>Document</title>
</head>
<body>
  <script>
    new Home.Page();
  </script>
</body>
</html>

命名空间可以嵌套

namespace Components{
  export namespace SubComponents{
    export class Test{}
  }
}

配置ts转js只生产一个文件

在这里插入图片描述
在这里插入图片描述
amd的语法无法直接被浏览器识别,需要引入一个插件require.js

十.TypeScript的import写法

compontens.ts

  export class Header{
    constructor(){
      const elem = document.createElement('div');
      elem.innerText = 'this is header';
      document.body.appendChild(elem);
    }
  }
  export class Content{
    constructor(){
      const elem = document.createElement('div');
      elem.innerText = 'this is Content';
      document.body.appendChild(elem);
    }
  }
  export class Footer{
    constructor(){
      const elem = document.createElement('div');
      elem.innerText = 'this is Footer';
      document.body.appendChild(elem);
    }
  }

page.ts

import { Header, Content , Footer} from "./components";
  export default class Page{
    constructor(){
      new Header();
      new Content();
      new Footer();
    }
  }


index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.js"></script>
  <script src="./build/page.js"></script>
  <title>Document</title>
</head>
<body>
  <script>
    require(['page'],function(page){
      new page.default();
    })
    
  </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值