ts 基础
ts 基础
基础类型
布尔
let bool: boolean = false;
数字
let num: number = 0;
字符串
let str: string = 'string';
let str: string = `string`;
数组
let arr: number[] = [1, 2, 3];
// 泛型
let arr: Array<number> = [1, 2, 3];
元组
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
let x: [string, number] = ['1', 1];
any
any 类型编译时可选择地包含或移除类型检查。
let x: any = 2;
x = '2';
x = {};
x = [];
void
void 类型表示没有任何类型,当一个函数没有返回值时,你通常会见到其返回值类型是 void。
function fn(): void {}
Null 和 Undefined
默认情况下 null 和 undefined 是所有类型的子类型。 就是说你可以把 null 和 undefined 赋值给 number 类型的变量。
let u: undefined = undefined;
let n: null = null;
然而,当你指定了--strictNullChecks 标记,null 和 undefined 只能赋值给 void 和它们各自。也许在某处你想传入一个 string 或 null 或 undefined,你可以使用联合类型。
let u: undefined | string = undefined;
let n: null | string = null;
类型断言
类型断言有两种形式。 其一是“尖括号”语法。
let someValue: any = 'this is a string';
let strLength: number = (<string>someValue).length;
另一个为 as 语法。
let someValue: any = 'this is a string';
let strLength: number = (someValue as string).length;
当你在 TypeScript 里使用 JSX 时,只有 as 语法断言是被允许的。
接口
类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。
interface point {
x: string;
y: string;
}
可选属性
interface point {
x?: string;
y: string;
}
只读属性
interface point {
readonly x: string;
y: string;
}
函数类型
interface fn {
(x: string, y: string): boolean;
}
对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。
let fun: fn = (a, b) => {
return true;
};
可索引的类型
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ['Bob', 'Fred'];
类类型
实现接口
interface ClockInterface {
currentTime: Date;
setTime(d: Date);
}
class Clock implements ClockInterface {
currentTime: Date;
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) {}
}
继承接口
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
混合类型
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;
接口继承类
class Control {
private state: any;
}
interface SelectableControl extends Control {
select(): void;
}
类
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return 'Hello, ' + this.greeting;
}
}
继承
在构造函数里访问 this 的属性之前,我们 一定要调用 super()。
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
。
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
只能在声明它的类的内部访问。
class Animal {
private name: string;
constructor(theName: string) {
this.name = theName;
}
}
protected
修饰符与 private 修饰符的行为很相似,成员在派生类中仍然可以访问。
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
只读属性必须在声明时或构造函数里被初始化。
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。
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!');
}
}
}
静态属性
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) {}
}
抽象类
抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 必须在派生类中实现,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。 抽象方法的语法与接口方法相似。
abstract class Animal {
abstract makeSound(): void;
move(): void {
console.log('roaming the earch...');
}
}
函数
函数类型
function add(x: number, y: number): number {
return x + y;
}
let myAdd = function (x: number, y: number): number {
return x + y;
};