typescript入门

typescript入门

1、环境
* 需要nodejs环境
* 安装:npm i -g typescript
* 查看版本:tsc -V
* 手动编译:tsc helloworld.ts
2、基本数据类型
名称 类型
布尔值 boolean
数字 number
字符串 string
undefined和null undefined/null
数组 number[]/Array<number>
元祖 [string,number,boolean]
枚举 enum Color{red=1,green,blue}
console.log(Color[1]) //red
any和void any/void
object object
联合类型 string|number
类型断言 (<string>str)/(str as string)
类型推断 let a=100 //number类型
let a //any类型
备注 首字母大写为包装类型,首字母小写为基本数据类型
3、接口
a、普通接口
interface IPerson {
  // 只读
  readonly name: string
  // 可有可无
  age?: number
}
b、函数式接口(只有一个方法的接口)
interface IPerson {
  (arg:string):boolean
}
c、未知属性接口
interface IProp{
  [propName:string]:any
}
d、数组接口
interface IArr{
  [index:number]:any
}
4、类
class Person {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  sleep() {
    console.log(this.name, this.age)
  }
}
5、继承
interface IPerson {
  sleep(arg: string): boolean
}

interface IAnimal extends IPerson {
  eat(arg: number): boolean
}

class Person implements IAnimal {
  gender: string

  constructor(gender: string) {
    this.gender = gender;
  }

  eat(arg: number): boolean {
    return false;
  }

  sleep(arg: string): boolean {
    return false;
  }
}

class Animal extends Person {
  constructor(gender: string = '男') {
    super(gender);
  }

  work() {
    // super关键字只能访问父类的方法,不能访问属性
    super.sleep('aaa')
  }
}
6、多态
// 与java不同,typescript无法强制类型转换
let person: IAnimal = new Person()
7、访问修饰符
public(默认):本类、子类、外部可以访问
private:本类可以访问
protected:本类、子类可以访问
readonly:只读修饰符(只能在构造函数中修改属性值)
备注:访问修饰符也可用在构造函数的参数上,此时构造函数的参数会成为类的属性
8、存取器(getter和setter)
// 只设置getter那就只能读,只设置setter那就只能写,都不设置或都设置可读可写
class Animal {
  private _name: string

  get name(): string {
    return this._name;
  }

  set name(value: string) {
    this._name = value;
  }
}
9、静态成员
// 与java不同实例对象无法访问静态成员
class Animal {
  // 类中有内置的name属性,所以name不能作为静态成员
  static age: number

  static eat() {
  }
}
10、抽象类
abstract class Animal {
  abstract name: string

  abstract eat()
}

class Person extends Animal {
  // 与java不同,抽象属性需要显式继承
  name: string;

  eat() {
  }
}
11、函数
// 方式一
function aaa(bbb: string): number {
  return 1
}

// 方式二
const bbb: (ccc: string) => number = function (ccc: string): number {
  return 1
}
12、参数
a、默认参数
function aaa(bbb: number = 1): void {
}
b、可选参数
function aaa(bbb?: number): void {
}
c、剩余参数(java叫动态参数)
// 剩余参数只能放在所有参数的最后
function aaa(...bbb: number[]): void {
}
13、函数重载声明
function aaa(bbb: string, ccc: string): string
function aaa(bbb: number, ccc: number): number
function aaa(bbb, ccc) {
  return bbb + ccc
}
14、泛型
a、泛型函数
function aaa<K, V>(bbb: K, ccc: V): [K, V] {
  return [bbb, ccc]
}
b、泛型接口
interface aaa<K, V> {
  bbb: K

  ccc(): V
}
c、泛型类
class aaa<K, V> {
  bbb: K

  ccc: (ddd: V) => number = function () {
    return 1
  }
}
d、泛型约束
interface ILength {
  length: number
}

function aaa<T extends ILength>(bbb: T): number {
  return bbb.length
}
15、声明文件
/*
当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。
声明语句:如果需要ts对新的语法进行检查,需要要加载了对应的类型说明代码
  declare var $: (selector: string) => any;
声明文件:把声明语句放到一个单独的文件(jquery.d.ts)中,ts会自动解析到项目中所有声明文件
下载声明文件:npm install @types/jquery --save-dev
*/

import $ from "jquery"
$('选择器')
16、内置对象
a、ECMAScript的内置对象
Boolean
Number
String
Date
RegExp
Error
b、BOM和DOM的内置对象
Window
Document
HTMLElement
DocumentFragment
Event
NodeList
17、类型别名
a、自定义类型起别名
type aaa=string|number
b、限制字符串选择
type sex='男'|'女'
18、命名空间
// ES2015模块语法优于自定义TypeScript模块和名称空间
export namespace com{
  export namespace wuxi{
    export namespace web{
      export class Person {
        name:string

        constructor(name: string) {
          this.name = name
        }
      }
    }
  }
}
19、装饰器
a、普通装饰器(无法传参)
// 定义一个装饰器
function logger(params:Function) {
  // params参数为所装饰的类本身
  params.prototype.aaa = 123
  params.prototype.bbb = function() {
    return 456
  }
}

@logger
class Mapper {
  save() {
    console.log('新增')
  }
}
function logger(params:any) {
  // 会重写所装饰的类的属性和方法
  return class extends Mapper {
    baseMapper='baseMapper'

    constructor(baseMapper: string) {
      super(baseMapper)
      this.baseMapper = baseMapper
    }

    save() {
      console.log('打印', params)
      super.save()
    }
  }
}

@logger
class Mapper {
  baseMapper='mapper'

  constructor(baseMapper: string) {
    this.baseMapper = baseMapper
  }

  save() {
    console.log('新增')
  }
}
b、装饰器工厂(可传参)
// 定义一个装饰器
function logger(params:string) {
  return function(target:Function) {
    console.log(params)
    // target参数为所装饰的类本身
    console.log(target)
  }
}

@logger('日志')
class Mapper {
  save() {
    console.log('新增')
  }
}
c、属性装饰器
function logger(params:any) {
  // 修饰静态属性target为构造函数,修饰成员属性target为原型对象
  return function(target:any, attr:any) {
    console.log(target)
    console.log(attr)
    target[attr] = params
  }
}

class Mapper {
  @logger('日志')
  static baseMapper='baseMapper'

  @logger('日志')
  mapper='mapper'
}
d、方法装饰器
function logger(params:any) {
  // 修饰静态方法target为构造函数,修饰成员方法target为原型对象
  // methodName:方法名
  // desc:方法描述信息
  return function(target:any, methodName:any, desc:any) {
    console.log(params)
    console.log(target)
    console.log(methodName)
    console.log(desc)
    // desc.value为所修饰的方法的函数对象
    const fun = desc.value
    desc.value = function(obj:any) {
      console.log(obj)
      fun.apply(this, obj)
    }
  }
}

class Mapper {
  @logger('日志')
  save(obj:any) {
    console.log(obj)
  }
}
e、方法参数装饰器
function logger(params:any) {
  // 修饰静态方法target为构造函数,修饰成员方法target为原型对象
  // methodName:方法名
  // paramsIndex:参数索引
  return function(target:any, methodName:any, paramsIndex:any) {
    console.log(params)
    console.log(target)
    console.log(methodName)
    console.log(paramsIndex)
  }
}

class Mapper {
  save(@logger('日志')obj:any) {
    console.log(obj)
  }
}
f、装饰器的执行顺序
* 属性 -> 方法 -> 方法参数 -> 类
* 如果有多个同样的装饰器,它会先执行后面的
原文地址:https://www.cnblogs.com/linding/p/15074062.html