对象类型

定义对象类型的三种方式:

// 匿名
let person: { name: string; age: number };

// 接口
interface Person {
  name: string;
  age: number;
}
let person: Person;

// type
type Person = {
  name: string;
  age: number;
};
let person: Person;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

索引签名

interface Obj {
  a: string;
}

const obj: Obj = {
  a: "1",
};

obj.b = 2;
1
2
3
4
5
6
7
8
9

此时会出现错误提示Property 'b' does not exist on type 'Obj'。要想解决这个问题,要使用索引签名。

interface Obj {
  a: string;
  [index: string]: string | number;
}

const obj: Obj = {
  a: "1",
};

obj.b = 2;
1
2
3
4
5
6
7
8
9
10

接口里的方法

interface Student {
    firstName: string;
    lastName: string;
    age: number;
    // equals to
    // getSalary: (base: number) => number
    getSalary(base: number): number;
};
1
2
3
4
5
6
7
8

用接口描述函数

// declare a function type
interface IsSumOdd {
    ( a: number, b: number ): boolean;
}

// create a function of type `IsSumOdd`
let isSumOdd: IsSumOdd = ( x, y ) => {
    if( (x + y) % 2 === 0 ) {
        return false;
    }

    return true;
};

// make some `isSumOdd()` calls
console.log( 'isSumOdd(1, 2) =>', isSumOdd(1, 2) );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

带属性声明的函数类型

// declare a function type with properties
interface IsSumOdd {
    ( a: number, b: number ): boolean;
    type: string;
    calculate( a: number, b: number): number;
}

// create a function of type `IsSumOdd`
let isSumOdd: IsSumOdd = Object.assign(
    function( x: number, y: number ): boolean {
        return (x + y) % 2 !== 0;
    },

    // assign properties
    {
        type: 'oddChecker',
        calculate: function( x: number, y: number ): number {
            return x + y;
        }
    }
);

// log some values
console.log( 'isSumOdd(1, 2) =>', isSumOdd(1, 2) );
console.log( 'isSumOdd.type =>', isSumOdd.type );
console.log( 'isSumOdd.calculate(1, 2) =>', isSumOdd.calculate(1, 2) );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

构造函数

// define a class
class Animal {
    sound: string

    constructor( sound: string ) {
        this.sound = sound;
    }

    getSound(): string {
        return `${ this.sound }! ${ this.sound }!`;
    }
}

// define an interface to represent a constructor function
interface AnimalInterface {
    new ( sound: string ): Animal;
}

// create `Animal` factory function
let createAnimal = ( ctor: AnimalInterface, type: string ): Animal => {
    return type === 'dog' ? new ctor( 'Woof' ) : new ctor( 'Meow' );
}

// create `Animal` instance
let dog: Animal = createAnimal( Animal, 'dog' );
console.log( 'dog.getSound() =>', dog.getSound() );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

纯对象

interface SimpleObject {
  [key: string]: any;
}
1
2
3
// 这种方式定义的类型是除了基本类型之外的类型,不一定是纯对象
let simpleObj: object;

simpleObj = function (a: number, b: number) {
    return a + b;
}
1
2
3
4
5
6

接口继承

// define `Person` interface
interface Person {
    firstName: string;
    lastName: string;
}

// `Student` interface inherits `Person`
interface Student extends Person {
    rollNo: number;
}

// define `ross` object of type `Student`
let ross: Student = {
    firstName: 'Ross',
    lastName: 'Geller',
    rollNo: 100
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// define `Person` interface
interface Person {
    firstName: string;
    lastName: string;
}

// define `Player` interface
interface Player {
    score: number;
}

// `Student` interface inherits `Person` and `Player`
interface Student extends Person, Player {
    rollNo: number;
}

// create `ross` object of type `Student`
let ross: Student = {
    firstName: 'Ross',
    lastName: 'Geller',
    score: 85,
    rollNo: 100,
};

// log values
console.log( 'ross =>', ross );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

注意事项

解构赋值内无法添加类型声明

Note that there is currently no way to place type annotations within destructuring patterns. This is because the following syntax already means something different in JavaScript.

目前没有办法在解构赋值里添加类型声明,这是因为如下这种语法在 JavaScript 已经用于属性的重命名。

function draw({ shape: Shape, xPos: number = 100 /*...*/ }) {
    // Cannot find name 'shape'. Did you mean 'Shape'?
    render(shape);

    // Cannot find name 'xPos'.
    render(xPos);
}
1
2
3
4
5
6
7

在对象的解构赋值里,shape: Shape是说将属性shape在本地重命名为Shape;类似地,xPos: number创建了一个名为number的变量,其值基于属性xPos