随着 TypeScript 的不断发展,越来越多的开发者认可并使用 TypeScript 开发应用。本文档的目标是使 TypeScript 新特性的代码风格保持一致,并给予一些实践建议。
本文档基本遵循 JavaScript Style Guide 与 ES-Next Style Guide。
由于 TypeScript 依然在快速发展,本文档也将随时保持更新。更新内容主要涉及对新增的语言特性的格式规范化、实践指导,引擎与编译器环境变化的使用指导。
.ts
扩展名。含 JSX 语法的 TypeScript 文件使用 .tsx
扩展名。tsconfig.json
配置文件应开启 strict
、noImplicitReturns
、noUnusedLocals
选项。tsconfig.json
配置文件应开启 allowSyntheticDefaultImports
选项。示例:
// good
import React, { PureComponent } from 'react';
// bad
import * as React from 'react';
VS Code
编写 TypeScript。接口
使用 Pascal
命名法。接口名
不使用 I
作为前缀。示例:
// good
interface ButtonProps {
// ...
}
// bad
interface IButtonProps {
// ...
}
类型别名
使用 Pascal
命名法。示例:
// good
interface HeaderStateProps {
// ...
}
interface HeaderDispatchProps {
// ...
}
type HeaderProps = HeaderStateProps & HeaderDispatchProps;
const
声明 枚举
。示例:
// good
const enum Directions {
UP,
DOWM,
LEFT,
RIGHT,
}
// bad
enum Directions {
UP,
DOWN,
LEFT,
RIGHT,
}
示例:
// good
let shouldUpdate = false;
// bad
let shouldUpdate: boolean = false;
string / number / boolean
声明基本类型,不使用 String / Number / Boolean
。示例:
// good
let str: string;
// bad
let str: String;
Object / Function
声明类型。T[]
声明类型,否则应使用 Array<T>
。ReadonlyArray<T>
声明类型。示例:
// good
let files: string[];
let tokens: Array<string | number>;
let buffer: Buffer[];
let responses: Array<Promise<number>>;
// bad
let files: Array<string>;
let tokens: (string | number)[];
let buffer: Array<Buffer>;
let responses: Promise<number>[];
!
声明对象属性非空。示例:
// good
if (foo.bar && foo.bar.baz) {
// ...
}
// bad
if (foo!.bar!.baz) {
// ...
}
any
声明类型。示例:
// good
const identity = <T>(x: T) => x;
// bad
const identity = (x: any) => x;
as
进行类型声明转换,不使用 <>
。示例:
// good
const root = document.getElementById('root') as HTMLDivElement;
// bad
const root = <HTMLDivElement>document.getElementById('root');
示例:
// good
interface AnyInterface {
foo();
foo(x: string);
bar();
bar(x: number);
}
// bad
interface AnyInterface {
foo();
bar();
foo(x: string);
bar(x: number);
}
===
或 !==
判断相等性,不使用 ==
或 !=
。示例:
// good
if (foo !== null && foo !== undefined) {
// ...
}
// bad
if (foo != null) {
// ...
}
Object.keys / Object.values / Object.entries / Object.getOwnPropertyNames
遍历对象,不使用 for .. in
。示例:
// good
Object.keys(obj).forEach(key => /* ... */);
// bad
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
// ...
}
}
for .. of
遍历数组,不使用 for
。示例:
// good
for (const item of items) {
// ...
}
// bad
for (let i = 0; i < items.length; i++) {
const item = items[i];
// ...
}
...
进行数组浅拷贝,不使用 Array.from / Array.prototype.slice
。示例:
// good
const copies = [...items];
// bad
const copies = items.slice();
// worst
let copies = [];
for (let i = 0; i < items.length; i++) {
copies.push(items[i]);
}
...
将类数组对象转化为数组,不使用 Array.from / Array.prototype.slice
。示例:
// good
const elements = [...document.querySelectorAll('.foo')];
// bad
const element = Array.from(document.querySelectorAll('.foo'));
// worst
const element = Array.prototype.slice.call(document.querySelectorAll('.foo'));
...
进行对象浅拷贝,不使用 Object.assign
。示例:
// good
this.setState(state => ({...state, clicked: true}));
// bad
this.setState(state => Object.assign({}, state, {clicked: true}));
return undefined
,应直接 return
。示例:
// good
function foo(bar: boolean) {
if (!bar) {
return;
}
}
// bad
function foo(bar: boolean) {
if (!bar) {
return undefined;
}
}
public
时,不应显式声明。示例:
// good
class Button extends PureComponent<ButtonProps, ButtonState> {
readonly state: ButtonState = {
clicked: false,
};
render() {
// ...
}
}
// bad
class Button extends PureComponent<ButtonProps, ButtonState> {
public state: ButtonState = {
clicked: false,
};
constructor(props: ButtonProps) {
super(props);
}
public render() {
// ...
}
}
示例:
// good
class AppComponent {
constructor(private readonly heroService: HeroService) {}
}
// bad
class AppComponent {
private readonly heroService: HeroService;
constructor(heroService: HeroService) {
this.heroService = heroService;
}
}
ECMAScript 2015
标准的模块系统。module / namespace
关键字。/// <reference path= >
。示例:
// good
import foo from 'foo';
// bad
import foo = require('foo');
import
一次。示例:
// good
import React, {PureComponent} from 'react';
// bad
import React from 'react';
import {PureComponent} from 'react';
webpack
等构建工具的项目,在模块中引入其他资源(如样式、图片等)时,为资源编写类型声明文件,或使用合适的 loader
生成类型声明文件。示例:
// good
// Button.scss.d.ts
export clicked: string;
// logo.png.d.ts
declare const logo: string;
export default logo;
// Button.tsx
import styles from './Button.scss';
import logo from './logo.png';
// bad
const styles = require<any>('./Button.scss');
const logo = require<string>('./logo.png');