日常项目开发使用typescript

简介: 本文适合日常项目开发使用到TS、以及对TS感兴趣的小伙伴阅读。

一、前言


本文基于开源项目:

https://github.com/microsoft/TypeScript

https://www.typescriptlang.org/docs/

 

前阵子有小伙伴跟广东靓仔说自己在日常项目开发过程中有使用typescript,不过仅仅只是使用了基础的类型声明,有些时候项目时间赶甚至写了很多any。    


这里广东靓仔整理了一些日常项目开发使用typescript的小技巧,希望对小伙伴有所帮助。


二、TS基础知识


   Typescript的基础知识我们要牢牢掌握,有一句老话,楼房建得高不高,地基很重要。


  Typescript的基础类型基本都是小写字母开头的(除了Array),很多小伙伴忽略了这点。相信有小伙伴有使用过Number ,TS指导建议我们不要这样使用。我们都知道在JavaScript代码中几乎从不使用的非原始装箱对象。


/* WRONG */ 
function reverse(s: String): String; 
请使用类型数字,字符串和布尔值。
/* OK */ 
function reverse(s: string): string; 
/* OK */ 
let decLiteral: number = 6;


基础类型:

1、boolean

2、number

3、string

4、[]、Array<>


// 在元素类型后面接上[],表示由此类型元素组成的一个数组
let list: number[] = [1, 2, 3];
// 数组泛型,Array<元素类型>
let list: Array<number> = [1, 2, 3];


5、Tuple

// 声明一个元组
let x: [string, number];
// 正确的初始化
x = ['广东', 10]; // OK
// 错误的初始化
x = [10, '靓仔']; // Error


6、enum

const enum Directions {
  Up,
  Down,
  Left,
  Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]


7、any ---- 尽量不使用

8、void

9、undefined和null

10、never

function error(message: string): never {
    throw new Error(message);
}


11、类型断言:<>、as

类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构

温馨提示我们定义变量的时候,尽量使用let


三、tsconfig.json 字段说明


tsconfig.json 所包含的属性并不多,只有 7 个。  

tsconfig可以到http://json.schemastore.org/tsconfig查看,下面我们重点讲讲字段。


files: 数组类型,用于表示由 ts 管理的文件的具体文件路径

exclude: 数组类型,用于表示 ts 排除的文件(2.0 以上支持 Glob)

include: 数组类型,用于表示 ts 管理的文件(2.0 以上)

compileOnSave: 布尔类型,用于 IDE 保存时是否生成编译后的文件

extends: 字符串类型,用于继承 ts 配置,2.1 版本后支持

compilerOptions: 对象类型,设置编译的选项,不设置则使用默认配置,配置项比较多,后面再列

typeAcquisition: 对象类型,设置自动引入库类型定义文件(.d.ts)相关,该对象下面有 3 个子属性分别是:

   enable: 布尔类型,是否开启自动引入库类型定义文件(.d.ts),默认 false

   include: 数组类型,允许自动引入的库名,如:["jquery", "lodash"]

   exculde: 数组类型,排除的库名


如不设定 filesinclude,ts 默认是 exclude 以外的所有的以.ts .tsx 结尾的文件。如果,同时设置 files 的优先级最高,exclude 次之,include 最低。

上面都是文件相关的,编译相关的都是靠 compilerOptions 设置的,接着就来看一看。


属性名

值类型

默认值

描述

allowJs boolean false 编译时,允许有 js 文件
baseUrl string
与 path 一同定义模块查找的路径
declaration boolean false 生成 .d.ts 定义文件
jsx string "preserve" jsx 的编译方式
noImplicitAny boolean false 不允许隐式 any,如果true,函数的形参必须带类型,如果叫不出class名的js对象,那就得any,比如(d:any)=>{}

如果false,函数的样子更像js  (d)=>{

............

............一般情况下,tsconfig.json 文件只需配置 compilerOptions 部分。


{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true, // 允许引入没有默认导出的模块
    "module": "es2015",
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true,
    "strict": true,
    "target": "es5",
    "lib": [
      "dom",
      "es5",
      "es2015"
    ]
  }
}


allowSyntheticDefaultImports 是使用 vue 必须的,而设置 module 则是让模块交由 webpack 处理,从而可以使用 webpack2 的摇树。另外,加上allowJs,这样就可以一点点将现有的 js 代码转换为 ts 代码了。


如果,在 webpack 中设置过 resolve -> alias,那么,在 ts config 中也需要通过 baseUrl + path 的方式来定义模块查找的方式。


<a name="tslint"></a>


四、ts使用小技巧


1.注释

我们平时开发过程可以通过 /** */ 形式的注释可以给 TS 类型做标记提示,这样子编辑器会有更好的提示。

/** This is a cool guy. */
interface Person {
  /** This is name. */
  name: string,
}
const p: Person = {
    name: 'cool'
}


当我们鼠标移动到person会有tooltip,一眼就看出来是什么了。

image.png


2.接口继承


和类一样,接口也是可以相互继承。让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。


interface Shape {
    color: string;
}
interface Square extends Shape {
    sideLength: number;
}
let square = <Square>{};
square.color = "blue";
square.sideLength = 10;


一个接口可以继承多个接口,创建出多个接口的合成接口。

interface Shape {
    color: string;
}
interface PenStroke {
    penWidth: number;
}
interface Square extends Shape, PenStroke {
    sideLength: number;
}
let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;


3interface & type

TypeScript 定义类型的两种方式:接口(interface)和 类型别名(type alias)。

比如下面的 Interface 和 Type alias 的例子中,除了语法,意思是一样的:


Interface

interface Place {
  x: number;
  y: number;
}
interface SetPlace {
  (x: number, y: number): void;
}


Type alias

type Place = {
  x: number;
  y: number;
};
type SetPlace = (x: number, y: number) => void;

而且两者都可以扩展,但是语法有所不同。此外,请注意,接口和类型别名不是互斥的。接口可以扩展类型别名,反之亦然。


4. typeof

typeof可以获取一个对象/实例的类型

typeof 只能用在具体的对象上,这与 js 中的 typeof 是一致的,并且它会根据左侧值自动决定应该执行哪种行为。


interface Opt {
  timeout: number
}
const defaultOption: Opt = {
  timeout: 500
}


有时候可以反过来:

const defaultOption = {
  timeout: 500
}
type Opt = typeof defaultOption


5. 运算符


非空断言运算符 !

这个运算符可以用在变量名或者函数名之后,用来强调对应的元素是非 null|undefined 的。

function onClick(callback?: () => void) {
  callback!();  // 参数是可选入参,加了这个感叹号!之后,TS编译不报错
}


   这个符号的场景,特别适用于我们已经明确知道不会返回空值的场景,从而减少冗余的代码判断,如 React 的 Ref。

function Demo(): JSX.Elememt {
  const divRef = useRef<HTMLDivElement>();
  useEffect(() => {
    divRef.current!.scrollIntoView(); 
    // 当组件Mount后才会触发useEffect,故current一定是有值的
  }, []);
  return <div ref={divRef}>Demo</div>
}


可选链运算符 ?.

?.这个是开发者最需要的运行时(当然编译时也有效)的非空判断。

obj?.prop
obj?.[index]
func?.(args)

?.用来判断左侧的表达式是否是 null | undefined,如果是则会停止表达式运行,可以减少我们大量的&&运算。

比如我们写出a?.b时,编译器会自动生成如下代码

a === null || a === void 0
 ?
  void 0
 :
  a.b;

这里涉及到一个小知识点:undefined这个值在非严格模式下会被重新赋值,使用void 0必定返回真正的 undefined。


空值合并运算符 ??

??与||的功能是相似的,区别在于??在左侧表达式结果为 null 或者 undefined 时,才会返回右侧表达式。

比如我们书写了let b = a ?? 10,生成的代码如下:

let b = a !== null && a !== void 0
 ?
  a
 :
  10;

而 || 表达式,大家知道的,则对 false、''、NaN、0 等逻辑空值也会生效,不适于我们做对参数的合并。


数字分隔符_

let num:number = 1_2_345.6_78_9

_可以用来对长数字做任意的分隔,主要设计是为了便于数字的阅读,编译出来的代码是没有下划线的。


五、总结


   typescript我们可以在Vue中引入,广东靓仔之前写过Vue+ts+vuex的相关文章,我们可以使用vue 支持 jsx,进而使用render jsx。当然我们也可以在React中引typescript    总体来说ts其实对于规模较大的前端团队来说,还是很有必要的。

相关文章
|
JavaScript 前端开发 编译器
TypeScript:熟练掌握TypeScript(四)
TypeScript:熟练掌握TypeScript(四)
113 0
|
JavaScript 前端开发 Java
TypeScript:熟练掌握TypeScript(三)
TypeScript:熟练掌握TypeScript(三)
167 0
|
3月前
|
JavaScript 前端开发 安全
TypeScript在项目中应用
【8月更文挑战第4天】TypeScript在项目中应用
37 0
|
5月前
|
JavaScript 前端开发 安全
TypeScript如何提高开发效率?
【6月更文挑战第1天】TypeScript如何提高开发效率?
68 5
|
6月前
|
JavaScript 前端开发 IDE
使用TypeScript进行现代JavaScript开发
【5月更文挑战第15天】TypeScript是JavaScript的超集,提供静态类型检查、接口、类和更好的工具支持,提升代码质量和开发效率。它的关键特性包括类型注解、接口和泛型。在使用时,建议逐步引入到现有项目,充分利用IDE,编写清晰的类型定义,并使用linting工具。TypeScript是现代JavaScript开发的有力工具,尤其适合大型项目。
|
6月前
|
JavaScript 开发者
【TypeScript 技术专栏】TypeScript 与 ESLint 代码规范
【4月更文挑战第30天】TypeScript和ESLint是代码规范的关键工具。TypeScript通过静态类型检查、接口与模块系统提升代码质量;ESLint则负责语法检查、风格统一和最佳实践。两者结合使用,提供全面的代码规范保障。制定团队共识、保持灵活性并持续优化规范是关键。常见问题包括类型不匹配、风格不一致和未使用变量,可通过这两工具解决。实际案例分析进一步说明了它们在项目中的应用。重视代码规范,利用这些工具,能提高代码质量和开发效率。
159 0
|
6月前
|
JavaScript 安全 编译器
【TypeScript 技术专栏】TypeScript 与 Jest 测试框架
【4月更文挑战第30天】本文探讨了TypeScript与Jest测试框架的结合在确保代码质量和稳定性上的重要性。Jest以其易用性、内置断言库、快照测试和代码覆盖率分析等特点,为TypeScript提供全面的测试支持。两者结合能实现类型安全的测试,提高开发效率,并涵盖各种测试场景,包括异步操作。通过实际案例分析,展示了如何有效利用这两个工具提升测试质量和开发效率,为项目成功奠定基础。
121 0
|
6月前
|
监控 JavaScript 前端开发
【TypeScript技术专栏】TypeScript的单元测试与集成测试
【4月更文挑战第30天】本文讨论了在TypeScript项目中实施单元测试和集成测试的重要性。单元测试专注于验证单个函数、类或模块的行为,而集成测试关注不同组件的协作。选用合适的测试框架(如Jest、Mocha),配置测试环境,编写测试用例,并利用模拟和存根进行隔离是关键。集成测试则涉及组件间的交互,需定义测试范围,设置测试数据并解决可能出现的集成问题。将这些测试整合到CI/CD流程中,能确保代码质量和快速响应变化。
202 0
|
6月前
|
JavaScript
【TypeScript学习】—TypeScript开发坏境搭建(一)
【TypeScript学习】—TypeScript开发坏境搭建(一)
|
JavaScript 前端开发 IDE
TypeScript基础
TypeScript基础
107 0
TypeScript基础