Skip to content

ts 基础

基础类型

布尔

ts
let bool: boolean = false

数字

ts
let num: number = 0

字符串

ts
let str: string = 'string'
let str: string = `string`

数组

ts
let arr: number[] = [1, 2, 3]

// 泛型
let arr: Array<number> = [1, 2, 3]

元组

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

ts
let x: [string, number] = ['1', 1]

any

any 类型编译时可选择地包含或移除类型检查。

ts
let x: any = 2
x = '2'
x = {}
x = []

void

void 类型表示没有任何类型,当一个函数没有返回值时,你通常会见到其返回值类型是 void。

ts
function fn(): void {}

Null 和 Undefined

默认情况下 null 和 undefined 是所有类型的子类型。 就是说你可以把 null 和 undefined 赋值给 number 类型的变量。

ts
let u: undefined = undefined
let n: null = null

然而,当你指定了--strictNullChecks 标记,null 和 undefined 只能赋值给 void 和它们各自。也许在某处你想传入一个 string 或 null 或 undefined,你可以使用联合类型。

ts
let u: undefined | string = undefined
let n: null | string = null

类型断言

类型断言有两种形式。 其一是“尖括号”语法。

ts
let someValue: any = 'this is a string'
let strLength: number = (<string>someValue).length

另一个为 as 语法。

ts
let someValue: any = 'this is a string'
let strLength: number = (someValue as string).length

当你在 TypeScript 里使用 JSX 时,只有 as 语法断言是被允许的。

接口

类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。

ts
interface point {
  x: string
  y: string
}

可选属性

ts
interface point {
  x?: string
  y: string
}

只读属性

ts
interface point {
  readonly x: string
  y: string
}

函数类型

ts
interface fn {
  (x: string, y: string): boolean
}

对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。

ts
let fun: fn = (a, b) => {
  return true
}

可索引的类型

ts
interface StringArray {
  [index: number]: string
}

let myArray: StringArray
myArray = ['Bob', 'Fred']

索引签名

如果你想定义一个具有任意属性的组件,可以使用索引签名。

ts
interface MyComponentProps {
  name:string,
  [propName: string]: any;
}

let myObj: MyComponentProps = {
  name:'xiaolin',
  age:18,
  address:'福建'
}

类类型

实现接口

ts
interface ClockInterface {
  currentTime: Date
  setTime(d: Date)
}

class Clock implements ClockInterface {
  currentTime: Date
  setTime(d: Date) {
    this.currentTime = d
  }
  constructor(h: number, m: number) {}
}

继承接口

ts
interface Shape {
  color: string
}

interface PenStroke {
  penWidth: number
}

interface Square extends Shape, PenStroke {
  sideLength: number
}

混合类型

ts
interface Counter {
  (start: number): string
  interval: number
  reset(): void
}

function getCounter(): Counter {
  let counter = <Counter>function (start: number) {}
  counter.interval = 123
  counter.reset = function () {}
  return counter
}

let c = getCounter()
c(10)
c.reset()
c.interval = 5.0

接口继承类

ts
class Control {
  private state: any
}

interface SelectableControl extends Control {
  select(): void
}

ts
class Greeter {
  greeting: string
  constructor(message: string) {
    this.greeting = message
  }
  greet() {
    return 'Hello, ' + this.greeting
  }
}

继承

在构造函数里访问 this 的属性之前,我们 一定要调用 super()。

ts
class Animal {
  name: string
  constructor(theName: string) {
    this.name = theName
  }
  move(distanceInMeters: number = 0) {
    console.log(`${this.name} moved ${distanceInMeters}m.`)
  }
}

class Snake extends Animal {
  constructor(name: string) {
    super(name)
  }
  move(distanceInMeters = 5) {
    console.log('Slithering...')
    super.move(distanceInMeters)
  }
}

class Horse extends Animal {
  constructor(name: string) {
    super(name)
  }
  move(distanceInMeters = 45) {
    console.log('Galloping...')
    super.move(distanceInMeters)
  }
}

公共,私有与受保护的修饰符

默认为public

ts
class Animal {
  name: string
  constructor(theName: string) {
    this.name = theName
  }
  move(distanceInMeters: number) {
    console.log(`${this.name} moved ${distanceInMeters}m.`)
  }
}

class Animal {
  public name: string
  public constructor(theName: string) {
    this.name = theName
  }
  public move(distanceInMeters: number) {
    console.log(`${this.name} moved ${distanceInMeters}m.`)
  }
}

private只能在声明它的类的内部访问。

ts
class Animal {
  private name: string
  constructor(theName: string) {
    this.name = theName
  }
}

protected修饰符与 private 修饰符的行为很相似,成员在派生类中仍然可以访问。

ts
class Person {
  protected name: string
  constructor(name: string) {
    this.name = name
  }
}

class Employee extends Person {
  private department: string

  constructor(name: string, department: string) {
    super(name)
    this.department = department
  }

  public getElevatorPitch() {
    return `Hello, my name is ${this.name} and I work in ${this.department}.`
  }
}

readonly

只读属性必须在声明时或构造函数里被初始化。

ts
class Octopus {
  readonly name: string
  readonly numberOfLegs: number = 8
  constructor(theName: string) {
    this.name = theName
  }
}

// 使用参数属性初始化
class Octopus {
  readonly numberOfLegs: number = 8
  constructor(readonly name: string) {}
}

存取器

只带有 get 不带有 set 的存取器自动被推断为 readonly。

ts
class Employee {
  private _fullName: string

  get fullName(): string {
    return this._fullName
  }

  set fullName(newName: string) {
    if (passcode && passcode == 'secret passcode') {
      this._fullName = newName
    } else {
      console.log('Error: Unauthorized update of employee!')
    }
  }
}

静态属性

ts
class Grid {
  static origin = { x: 0, y: 0 }
  calculateDistanceFromOrigin(point: { x: number; y: number }) {
    let xDist = point.x - Grid.origin.x
    let yDist = point.y - Grid.origin.y
    return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale
  }
  constructor(public scale: number) {}
}

抽象类

抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 必须在派生类中实现,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。 抽象方法的语法与接口方法相似。

ts
abstract class Animal {
  abstract makeSound(): void
  move(): void {
    console.log('roaming the earch...')
  }
}

函数

函数类型

ts
function add(x: number, y: number): number {
  return x + y
}

let myAdd = function (x: number, y: number): number {
  return x + y
}