# 提示与建议

# 1. 名义化类型

TS 是结构化类型,可以通过一些特殊的手段来达到名义化类型的效果

使用字面量类型:

type Id<T extends string> = {
  type: T;
  value: string;
};

type PersonId = Id<'Person'>;
type StudentId = Id<'Student'>;

let pId: PersonId = { type: 'Person', value: '123' };
let sId: StudentId = { type: 'Student', value: '456' };

# 2. 科里化

使用一系列箭头函数的功能

const add = (x: number) => (y: number) => (z: number) => x + y + z;

add(1)(2)(3);

# 3. 对象字面量的惰性初始化

这样初始化一个对象:

let person = {};

person.name = '张三'; // 错误:Property 'name' does not exist on type '{}'.

在变量赋值的同时,添加属性和值:

let person = {
  name: '张三',
};

断言为 any:

let person = {} as any;

person.name = '张三';

使用接口:

interface IPerson {
  name: string;
}

let person = {} as IPerson;

person.name = '张三';

# 4. 用类组织代码

class Person {
  id: string;
  name: string;
  age: string;

  constructor() {
    // 初始化代码
  }

  someMethods() {

  }

  someUtilities() {

  }
}

export default new Person();

# 5. 不建议默认导出

// person.ts:
class Person {}

export default Person;


// main.ts
import Person from './person';

可维护性差:

  • 重构 person.ts,将 Person 改为 Student, 导入语句中的 person 不会同步变化
  • 你期望 import Person from './person'; , 但别人可能会写成 import p from './person';

使用 CommonJS 和 import() 需要显式给 default 重命名:

const { default: Person } = require('./person');


import('./person').then(({ default: Person }) => {
  // ...
})

# 6. 减少 setter 属性的使用

class Person {
  name: string;

  // 不建议使用 setter
  set foo(name: string) {
    this.name = name;
  }

  setFoo(name: string) {
    this.name = name;
  }
}

# 7. 函数参数

通过函数有很多个参数,或多个相同类型的参数,建议改为对象形式的参数:

function findImage(imageName: string, sim: number, rows: number, cols: number, selectRow: number, selectCol: number) {
  // ...
}

function findImage2(params: { imageName: string, sim: number, rows: number, cols: number, selectRow: number, selectCol: number }) {
  // ...
}

# 8. 合并导出

将多个模块的导出合并到一个模块中去:

export * from './student';

import * as Teacher from './teacher';
export { Teacher }

# 9. 装饰器

参考:

本章目录