TypeScript_面向对象

测试环境

Playground TypeScript

babeljs try it out

基本类型

any
void

boolean
number
string

null
undefined

string[]          /* or Array<string> */
[string, number]  /* tuple */

string | null | undefined   /* union */

never  /* unreachable */

enum Color {Red, Green, Blue = 4}
let c: Color = Color.Green

声明

let isDone: boolean
let isDone: boolean = false

function add (a: number, b: number): number {
  return a + b
}

// Return type is optional
function add (a: number, b: number) { ... }

类是Typescript的核心,使用TypeScript开发时,大部分代码都是写在类里面的。

类的定义
class Point {
    x // 属性
    sayX () {} // 方法
}

// 实例化
let p = new Ponit()
p.x = 100
访问控制符

控制是否在类(本类)的外部访问到

class Point {
    public x // 公开的,默认 (类内,类外都可以访问到)
    protected y //  受保护的 (在本类和子类访问到)
    private z // 私有的 (在本类的内部访问到)
    sayX () {}
}
构造函数

constructor外部没法访问都构造函数方法,执行时间是在new构造函数的执行

class Point {
    constructor (public name: string) { // 参数中public会在类中声明一个name变量
    }
}
类的继承

extends声明类的继承关系
super调用父类的构造函数或者方法

class Point {
    x: string
    constructor (x: string) {
        this.x = x
    }
    sayX () {
        console.log(this.x)
    } 
}
class Person extends Point {
    code: number
    construcotr () {
        super('10') // 子类的构造函数必须要调用父类的构造函数
        super.sayX() // 子类调用父类方法
    }
}

let p1 = new Person()
p1.x = 'HelloWorld'
静态方法&静态属性
class Point {
    static x:string // 静态属性
    static sayX () {} // 静态方法
}

Point.x = 'HelloWorld'
Point.sayX()
常用的结构
class Point {
  x: number
  y: number
  static instances = 0
  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }
}

泛型

泛型(generic)
参数化的类型,一般用来限制集合的内容。

函数指定类型,泛型类型的函数。

// 泛型函数

// 定义
function Test<T> (arg: T):T {
    return arg
}

// 调用
Test<string>('hw')
Test<number>(100)
Test(false)

class Point {
    x: string
    sayX () { }
}

let pArr: Array<Point> = [] // 在为pArr指定类型为数组的时候,也指定数组中的参数化类型 
// 规定了pArr中只能放置Point类型的数据,可以是子类
pArr[0] = new Point()

// pArr[1] = 100 // 报错 // Type '100' is not assignable to type 'Point'.

// 泛型类
class Greeter<T> {
  greeting: T
  add:(x: T, Y: T) => T 
  constructor(message: T) {
    this.greeting = message
  }
}

let greeter = new Greeter<string>('Hello, world') // 实例化确定泛型类型

泛型根据所传递的类型,来决定方法中具有哪些属性。

接口

接口Interface:
用来建立某种代码约定,使得其它开发者在调用某个方法或创建新的类时必须遵循接口所定义的代码约定

Interfac声明接口
implements声明某个类来实现某个接口

典型用法

作为方法的参数类型声明

TypeScript会检查传入的参数是否满足符合的接口定义的所有属性

interface IPoint {
    name: string
    age: number
}

class Point {
    constructor(public config: IPoint) { // 作为方法的参数类型声明
    }
}

let p = new Point({name: 'hello', age: 18})
一个类实现某一个接口

一个类实现某一个接口,必须实现接口中定义的方法

interface IPonit {
    say()
}

class Point implements IPonit { // 一个类实现某一个接口
    say() {}
}

方式

内联
function printLabel (options: { label: string }) {
  console.log(options.label)
}

// Note the semicolon
function getUser (): { name: string; age?: number } {
}
显式声明
interface LabelOptions {
  label: string
}

function printLabel(options: LabelOptions) { ... }
可选属性
interface User {
  name: string,
  age?: number
}
只读
interface User {
  readonly name: string
}
Dynamic keys
{
  [key: string]: Object[]
}

模块

模块(Module):
模块可以帮助开发者将代码分割为可重用的单元。开发者可以自己决定将模块中的那些资源(类,方法,变量)暴露出去供外部使用,那些资源只在模块内部使用。

TypeScript中,一个模块就是一个文件,并没有特殊关键字来声明.

export

对外暴露一些东西

export interface User { ... }
export name
export function fun1 () { ... }
export class Point { ... }
import

引入某个模块

import { fun1, name } ''

注解

注解 (annotation):
注解为程序的元素(类,方法,变量)加上更直观更明了的说明,这些说明信息与程序的业务逻辑无关,而是供指定的工具或框架使用的。

import { Componet } from '@angular/core'

// 告知ng2怎么来处理AppComponent类
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})


export class AppComponent {
    title = 'app works!'
}

可以注解在属性上,也可以注解在方法上

类型定义文件

类型定义文件(*.d.ts)

类型定义文件用来帮助开发者在TypeScript中使用已有的JavaScript的工具包。
如:jQuery

安装类型定义文件工具: typings

引入jQueryTypeScript的部分代码:

declare module "jquery" {
    export = $
}

declare var jQuery: JQueryStatic
declare var $: JQueryStatic

declare module 'fastclick'

declare module 'vue-lazyload'

TS 的核心在于静态类型,在编写TS的时候会定义很多的类型,但是主流的库都是JS编写的,并不支持类型系统。那么如何让这些第三方库也可以进行类型推导呢?所以,需要一个d.ts文件来标记某个js库里面对象的类型。

TS目前作用就是:类型声明帮助编译器识别类型(编辑器的智能提示),遵循TS原则,先声明后使用。

d.ts文件就是作为一些复合类型、类、函数 其行为的约定 (类似于C++的头文件)

typings作用:一个网络上的d.ts的数据库

如何编写d.ts

变量,常量
declare let test: number // 变量
declare const max: 200 // 常量
函数
declare function getName(id:number | string): string
declare function reander(callback?: () => void): string
class
declare class Persion {
    static maxAge: number // 静态变量
    static getMaxAge(): number // 静态方法

    consturctor(name: string, age: number) // 构造函数
    getName(id: number): string

    app: Vue
    beforeEach (guard: NavigationGuard): Function
}
命名空间
declare namespace OOO {
    var aaa: number | string;
    function getName(id: number | string): string;
    class Person {
        static maxAge: number // 静态变量
        static getMaxAge(): number // 静态方法
        constructor(name: string, age: number) // 构造函数
        getName(id: number): string // 实例方法
    }
}
模块化
declare module 'test' {
    export let height: number;
    export namespace c {
        let title: string
    }
}

使用

let test = require('test')

模块和命名空间使用一种,一般使用模块。

declare module AA {
  type test = string;
  function require(moduleName: string): any;
}

生成d.ts文件:

tsc -d
tsc --declaration

函数新特性

generator 函数

简单的generator函数

function* doSomething () {
    console.log('start')
    yield
    console.log('finsh')
}

var fun1 = doSomething()

fun1.next() // start
fun1.next() // finsh

generator函数返回值

function* getStockPrice() {
    while (true) {
        yield Math.random() * 100
    }
}

var priceGenerator = getStockPrice()
var limitPrice = 15
var price = 100

while (price > limitPrice) {
    price = priceGenerator.next().value
    console.log(`price: ${price}`)
}

相关推荐