目的

用更合理的方式书写 Typescript

规范的代码可以促进团队合作,
规范的代码可以减少bug 处理,
规范的代码可以降低维护成本,
规范的代码有助于代码审查,
养成代码规范的习惯,有助于程序员自身的成长

名词解释

  • 大驼峰PascalCase
  • 小驼峰camelCase

    命名及约定

    Variable and Function(变量和函数)

  • 尽可能使用完整的单词拼写命名。语义化 ```javascript // Good const validateUserInfo = (id:string)=>{}

// Bad const valUsr = (id:string)=>{}

  1. - 使用string/number/boolean声明基本类型,不是用String/Number/Boolean包装类型。
  2. ```javascript
  3. // Good
  4. const name:string = "pis"
  5. // Bad
  6. const name:String = "uncle"
  • 不使用Function声明类型

    1. type FunctionTypes = {
    2. onSomething: Function; // ❌ bad,不推荐。任何可调用的函数
    3. onClick: () => void; // ✅ better ,明确无参数无返回值的函数
    4. onChange: (id: number) => void; // ✅ better ,明确参数无返回值的函数
    5. onClick(event: React.MouseEvent<HTMLButtonElement>): void; // ✅ better
    6. };
  • 对象类型尽量使用Record 代替{} 和object

    1. // good
    2. const person:Record<string,unknow> = {
    3. name:'pis',
    4. age:18
    5. }
    6. // bad
    7. const person:object = {
    8. name:'pis'
    9. }
  • 使用小驼峰给变量和函数命名

    Use camelCase for variable and function names

  1. //Good
  2. var fooVar;
  3. function barFunc() { }
  4. //Bad
  5. var FooVar;
  6. function BarFunc() { }
  • 数组元素为简单类型时,使用T[]声明类型;否则应使用Array ```javascript // Good const ids: string[] const response:Promise>>

// Bad const ids: Array const response:Promise>

  1. <a name="rVfpT"></a>
  2. ## namespace 命名空间
  3. - 使用大驼峰对命名空间namespace进行命名
  4. ```javascript
  5. // Good
  6. export default namespace UserService {
  7. export async function getUser(){}
  8. }
  9. // Bad
  10. export default namespace user_service {
  11. export async function getUser(){}
  12. }

type 类型

  • 使用大驼峰为类型type命名。 ```javascript // Good type Person {}

// Bad type person{}

  1. - 不应显式声明可以自动推导的类型
  2. ```javascript
  3. // Good
  4. let shouldUpdate = false;
  5. // Bad
  6. let shouldUpdate: boolean = false;

Class 类

  • 使用大驼峰对类class进行命名

    Use PascalCase for class names.

  1. //Good
  2. class Foo { }
  3. // Bad
  4. class foo { }
  • 使用小驼峰对类成员(变量和方法)进行命名

    Use camelCase of class members and methods

  1. // Good
  2. class Foo {
  3. bar: number;
  4. baz() { }
  5. }
  6. // Bad
  7. class Foo {
  8. Bar: number;
  9. Baz() { }
  10. }
  • 不要为私有属性名添加_前缀。 ```javascript //Good const locaVariable

// Bad const _localVariable

  1. <a name="UWGDA"></a>
  2. ## Interface 接口
  3. - 使用大驼峰对接口interface进行命名
  4. - 不要使用I做为接口名前缀。
  5. > Use PascalCase for name.
  6. ```javascript
  7. // good
  8. interface ButtonProps {
  9. // ...
  10. }
  11. // bad
  12. interface IButtonProps {
  13. // ...
  14. }

Enum 枚举

  • 使用大驼峰对枚举enum进行命名 ```javascript /* Good / export enum OperationType {

    /* 新增操作 / POST = ‘POST’,

    /* 删除操作 / DELETE = ‘DELETE’,

    /* 更新操作 / PUT = ‘PUT’,

    /* 批量更新操作 / PATCH = ‘PATCH’,

    /* 获取操作 / GET = ‘GET’, }

/* Bad / export enum OPERATION_TYPE {

/* 新增操作 / POST = ‘POST’,

/* 删除操作 / DELETE = ‘DELETE’,

/* 更新操作 / PUT = ‘PUT’,

/* 批量更新操作 / PATCH = ‘PATCH’,

/* 获取操作 / GET = ‘GET’, }

  1. <a name="jlqv1"></a>
  2. # 类型定义
  3. - 在一个文件里,类型定义应该出现在顶部。(import之后)
  4. - 不要导出类型/函数,除非你要在不同的组件中共享它。
  5. - 不要在全局命名空间内定义类型/值。
  6. - 共享的类型应该在types.ts里定义。
  7. <a name="q1Z5V"></a>
  8. # 文件名
  9. - 名词开头的文件名
  10. - 使用破折号(-)分割描述性单词或者大驼峰,这两种命名方式都被允许,但是一个项目中只能用其中一种
  11. ```javascript
  12. // Good
  13. user-list.ts
  14. UserList.ts
  • 动词开头的文件名使用小驼峰

    1. // Good
    2. getName.ts
    3. fetchUserInfo.ts
  • 使用点(.)将描述性名称与类型分开

    1. // Good
    2. interface.d.ts

    函数

  • 返回值会被忽略的回调函数设置返回值类型void,而不是any ```javascript // Good function fn(x: () => void) { x(); }

// Bad function fn(x: () => any) { x(); }

  1. - 不要函数的参数数量不同而编写不同的重载
  2. ```javascript
  3. // Good
  4. declare function beforeAll(action:boolean,timeout?: number): void;
  5. // Bad
  6. declare function beforeAll(action: boolean, timeout?: number): void;
  7. declare function beforeAll(action: boolean): void;

项目中最佳实践

引入React

  1. // 推荐使用✅ better 【最可靠的一种方式】
  2. import * as React from 'react'
  3. import * as ReactDOM from 'react-dom'
  4. // 需要添加额外的配置:"allowSyntheticDefaultImports": true
  5. import React from 'react'
  6. import ReactDOM from 'react-dom'

React函数组件声明

  • 如果该组件有 props,在组件上方写上对应声明类型并导出,类型名为 组件名 + Props
  • 组件比较推荐使用 React.FunctionComponent,简写形式:React.FC:React.FC 会提供默认的 children 类型,并将 props 的类型作为泛型参数传入 ```javascript import React from ‘react’

// 推荐使用✅ better 【大驼峰组件名+props】 // 推荐使用✅ better 【非必要不导出】 interface DemoComponentProps{ title?:string; } // 推荐使用✅ better 【组件名首字母大写】 // 推荐使用✅ better 【组件props如果是可选参数,最好给默认值】 const DemoComponent :React.FC = ({title=”我是title默认值”})=>{ // 推荐使用✅ better 【return的jsx最好使用圆括号进行包裹】 return (

{title}
) }

  1. <a name="MQx9L"></a>
  2. ## Hooks使用
  3. <a name="NQqjV"></a>
  4. ### 组件化书写规范
  5. > 推荐使用✅ 【组件的结构】
  6. - import 导入`**三方包和三方组件 [在最顶端]**`
  7. - import 导入`**自定义的包**`
  8. - import 导入 TS的类型是增加`**type关键字**`
  9. - import 导入 `**组件**`
  10. <a name="D04t9"></a>
  11. ### useState
  12. > 状态管理
  13. ```javascript
  14. // 推荐使用✅ better 【可以确定初始值的在声明的时候给默认值】
  15. const [ visible, toggleVisible] = useState<boolean>(false)
  16. // 推荐使用✅ better 【没有初始值赋予undefined或者null】
  17. const [username,setUserName] = useState<string|undefined>(undefined)

useEffect

副作用

  1. //异步请求,处理方式:
  2. // ✅ better 【自执行函数】
  3. useEffect(() => {
  4. (async () => {
  5. const { data } = await ajax(params);
  6. // todo
  7. })();
  8. }, [params]);
  9. // 或者 then 也是可以的
  10. useEffect(() => {
  11. ajax(params).then(({ data }) => {
  12. // todo
  13. });
  14. }, [params])

善用类型注释

  • 通过/* /形式的注视为Typescript类型做标记提示:
    1. /**
    2. * 卷位包含的配置信息
    3. */
    4. export interface rollSettingProps {
    5. /** 所属工单 */
    6. productionOrder?: string;
    7. /** 产品规格 */
    8. materialModel?: string;
    9. /** 卷位 */
    10. rollPosition?: number;
    11. /** 物料名称 */
    12. name?: string;
    13. /** 物料批次号 */
    14. batchNo?: string;
    15. /** 卷重 */
    16. weight?: number | undefined;
    17. /** 是否选中 */
    18. isSelected?: boolean;
    19. }

    鼠标悬浮的时候编辑器会有更好的提示

image.png

参考链接

Typescript cheatsheet
React + TypeScript实践