Appearance
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
}