1.基础类型

let isDone: boolean = false; // 布尔
let num: number = 6; // 数字(二进制,八进制,十六进制都可以)
let str: string = '6'; // 字符串
let str1: string = `this is ${str}` // 字符串
let list: number[] = [1,2,3]; // 元素数组
let list: Array<number> = [1,2,3] //数组泛型
let tuple:[string,number]; // 元组,允许表示一个已知数量和类型的数组
 tuple = ['6',6] // right
 tuple = [6,'6'] // wrong
 tuple[3] = 7 // right 当访问越界元素时使用联合类型代替(新元素number和string都可以,但不能有别的)
enum Color = {red = 1, green = 2, blue = 3} // 枚举,1,2,3代表元素编号
 let colorName = Color[2] // 'green'
let anyOne: any = 4; // 不确定类型的时候
// void表示没有任何类型,函数没有返回值时将返回类型设置为void
function warnUser(): void {
    console.log("This is my warning message");
}

其他的一些类型

1.null和undefined,默认情况下是所有类型的子类型,当指定了--strictNullChecks标记,nullundefined只能赋值给void和它们各自

2.never,表示永不存在的值的类型,可以赋值给任何类型,但是不能被任何类型赋值

// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
    throw new Error(message);
}

// 推断的返回值类型为never
function fail() {
    return error("Something failed");
}

// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
    while (true) {
    }
}

3.object, 非原始类型

declare function create(o: object | null): void;

create({ prop: 0 }); // OK
create(null); // OK

create(42); // Error
create("string"); // Error
create(false); // Error
create(undefined); // Error

4.类型断言(在编译阶段的类型转换)

let strLength: number = (<string>someValue).length;
let strLength: number = (someValue as string).length; //尽量用第二种,jsx下不支持第一种

2.接口

1.简单的接口定义

interface Example {
    label:string; // 字符串
    value:string|number; // 字符串或者数字
    notImportant?:string; // 不是必填,填的话是字符串
  readonly cannotwrite: number; // 只能在刚创建时赋值,不能修改
  [propName: string]: any; // 字符串索引签名
}
// 规定函数的输入&输出
function demo(config:Example):{num:number, str:string}{
  return {num:1,str:'1'}
}

let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a; // ro或者a都不能进行任何修改
a = ro as number[]; // 但是可以用类型断言重写

// 索引签名:number和string,但是number必须是string的子类型,因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象
class Animal {
    name: string;
}
class Dog extends Animal {
    breed: string;
}

// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!
interface NotOkay {
    [x: number]: Animal;
    [x: string]: Dog;
}

2.函数类型和类类型

interface SearchFunc {
  (source: string, subString: string): boolean; // 对应函数的输入为source和subString,输出为true/false
}

// 类类型
interface ClockInterface {
    currentTime: Date; // 描述某个类型
    setTime(d: Date); // 描述某个方法
}
 // 在类里实现这个接口
class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}
// tips:
// extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法; 
// implements 是实现多个接口, 接口的方法一般为空的, 必须重写才能使用 


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 很复杂的一个例子 
// 前提:类是具有两个类型的:静态部分的类型(constructor)和实例的类型。
interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
} // 描述了一个构造函数,返回的是一个实例方法
interface ClockInterface {
    tick();
} // 描述了一个方法
 

// 方法有三个入参,第一个入参是之前写的构造函数,后两个入参作为构造函数的入参
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
} // 返回值是接口方法的值,这个时候将ClockConstructor实例化了,返回的是ClockInterface,相当于为ClockInterface的函数传参h和m

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }// 静态类型,可以
    tick() {
        console.log("beep beep");
    }
} // 这个类中实现了ClockInterface方法,并将tick方法进行了重写
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}

let digital = createClock(DigitalClock, 12, 17); // 这个时候会先去检查DigitalClock是否符合ClockConstructor的接口定义
let analog = createClock(AnalogClock, 7, 32);

3.继承接口

interface Shape {
    color: string;
}
interface PenStroke {
    penWidth: number;
}

interface Square extends Shape,PenStroke {
    sideLength: number;
} // Square 现在有仨属性啦

4.接口继承类

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {
    select() { }
}

// 错误:“Image”类型缺少“state”属性。
// 只是SelectableControl的实现,但是没有继承Control类,因为不是Control的子类
class Image implements SelectableControl {
    select() { }
}

class Location {

}

类的基础请看es6相关语法,都差不多,在此记录一些不一样的

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

public:默认值

private:私有值,不能声明在它的类的外部访问,但是子类可以继承(extends)

protected:修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问,没办法在实例中使用,但是可以在派生类中访问中国属性

static:静态属性,在类本身才能调用的属性,实例想要访问的时候要加类名

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) { }
}

let grid1 = new Grid(1.0);  // 1x scale
let grid2 = new Grid(5.0);  // 5x scale

console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

abstract:抽象类,做为其它派生类的基类使用,用于定义抽象类和在抽象类内部定义抽象方法

函数

函数的基础声明跟基础类型,变量声明差不多,在此只记录一些特殊的

1.剩余参数

function buildName(firstName: string, ...restOfName: string[]) { // 剩余参数的设置
  return firstName + " " + restOfName.join(" ");
}

let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

泛型

function identity<T>(arg: T): T { // 这东东,可以理解为any类似功能
    return arg;
}

just小千
10 声望3 粉丝