为什么我们需要TypeScript?

TypeScript是微软公司为了给JavaScript添加类型特点而开发出来的一种开源编程语言,目前在前端的企业开发中经常使用到TypeScript。今天我给大家简要介绍一下TypeScript。

1、TypeScript的类型特点

TypeScript的类型特点简单说就是为JavaScript添加了静态类型。TypeScript通过TypeScript编译器或Babel转译为JavaScript代码,可运行在任何浏览器,任何操作系统上。目前由于TypeScript具备的静态类型,在开发阶段就可以减少很多bug从而在一定程度上提升开发效率,TypeScript在企业级前端开发中已经是一项普遍使用的技术了。

TypeScript常用类型

TypeScript常用类型(平时经常接触的)有number, string, boolean, 函数, array, any, void, object,示例代码如下:

// 1、数字类型 number
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n;

// 2、字符串类型 string
let color: string = "blue";

// 3、数组类型: array
let list: Array<number> = [1, 2, 3];
// or
interface User {
  name: string
}
const john = {name: 'john'}
const jack = {name: 'jack'}
let personList = [john, jack] // 这里 john 和 jack 都是 User 类型的

// 下面这种不是array, 是tuple, 后面会介绍
let l = ['jack', 10]

// 4、布尔值: boolean
let isDone: boolean = false;

// 5、函数: function
// 在js函数的基础上加参数类型和返回值类型
const isFalsy = (value: any): boolean => { 
  return value === 0 ? true : !!value; 
}; 

const isFalsy: (value: any) => boolean = (value) => {
  return value === 0 ? true : !!value;
};

// 6、any: any表示传入的值可为任意类型(不做类型检查) 
// 注意尽量在开发中不要使用any, 使用any会给代码带来不可控性!
let looselyTyped: any = 4;
// looselyTyped 的值明明是个4,哪里来的ifItExists方法呢?
// 由于声明为any,我们没法在静态检查阶段发现这个错误
looselyTyped.ifItExists();

// 7、void: 绝大部分情况下,只会用在这一个地方:表示函数不返回任何值或者返回undefined (因为函数不返回任何值的时候 === 返回 undefined)
export const useMount = (fn: () => void) => {
  useEffect(() => {
    fn();
  }, []);
};

// 8、object: 除了 number, string, boolean, bigint, symbol, null, or undefined,其他都是 object

比较少见的TypeScript类型

下面几种是比较少见的TypeScript类型,做前端的同学知道就行了:

// 1、tuple: 下面这种就是tuple("数量固定,类型可以各异" 版的数组)
const [users, setUsers] = useState([])

// 在 React 中有可能使用 tuple 的地方就是 custom hook 的返回值,注意 isHappy → tomIsHappy 以及其他名字的变化,这里使用tuple的好处就显现出来了:便于使用者重命名
const useHappy = () => {
   //....
   return [isHappy, makeHappy, makeUnHappy]
}

const SomeComponent = () => {
  const [tomIsHappy, makeTomHappy, makeTomUnHappy] = useHappy(false)
  // ...
}

// 2、enum: 枚举类型
export enum ITodoType {
  Task = 0,               // 未完成的任务
  Important = 1,          // 重要任务(标记了重要但未完成)
  Finished = 2            // 完成任务(标记了完成)
}

// 3、null 和 undefined:空 和 未定义
// null 和 undefined 在 TypeScript 中既是一个值,也是一个类型:
let u: undefined = undefined;
let n: null = null;

// 4、unknown: 表示这个值可以是任何值
// unknown 的用法:在你想用 any 的时候,用 unknown 来代替,简单来说,unknown是一个"严格"版的 any
const isFalsy = (value: unknown) => { 
 // 大家不用考虑这段console有啥意义,把它打在你的代码里对应的位置,观察编辑器会不会报错;
 // 再思考它应不应该报错
  console.log(value.mayNotExist)
  return value === 0 ? true : !!value; 
}; 

// 5、never
// 这个 func返回的就是never类型,用到比较少,在类型操作等场景会用到
const func = () => {
  throw new Error()
}

2、TypeScript的优缺点

下面把TypeScript和JavaScript结合对比,自行体会TypeScript的优缺点:

  • JavaScript不支持泛型,而TypeScript支持泛型。
  • JavaScript是解释性语言(大量错误要在运行时才能发现),而TypeScript需要对代码进行编译,在此过程中能解决大部分问题。
  • JavaScript在严格意义上只是脚本语言,而TypeScript全面支持面向对象的编程概念,如类、接口、继承、泛型等。
  • JavaScript不支持强类型或者静态类型,而TypeScript支持。
  • JavaScript文件名以.js结尾,而TypeScript文件名以.ts结尾。

我个人对TypeScript的具体使用感受如下:

  • 静态类型提高代码可读性: 与JavaScript相比,TypeScript增加的类型在开发的时候让各个参数的含义具体化
  • 泛型(类似C++)提高开发效率:通过写泛型的interface的方式来提前规定好交互数据的name和type
  • 代码检查: TypeScript的类型会在写代码的时候就进行静态检查(如果传错了就没法运行),而原生JavaScript在运行时才检查(运行时)。

3、在Vue和React项目中集成TypeScript

React集成TypeScript

我做的React项目基本上创建的时候就是用了TypeScript,使用create-react-app创建集成TypeScript的react项目的命令是:npx create-react-app my-app --template typescript

npx:是npm提供的一个工具(不下载包而使用最新的包),使用这个工具是为了跟最新的react框架对齐(这些主流开源框架经常更新的,创建项目时候最好用最新的包)

创建好了之后直接使用就行了,只不过注意几点:

  • JavaScript的文件后缀名是js,typescript的文件后缀名是ts
  • react中模板文件的后缀名是jsx,集成typescript的模板文件后缀名要使用tsx

react的模板文件:在这里面写react的jsx代码(HTML+JavaScript),jsx在上一次的文章简单介绍了一下

Vue集成TypeScript

没搞过,但是应该也不难,建议使用Vue开发项目的小伙伴在开发新项目时尝试使用最新的Vue3相关技术栈集成TypeScript。

联合类型、类型别名和interface

// 联合类型,下面的age可以是number或string类型 
let age = number | string;

// 赋值时
age = '7';
age = 7;

// 类型别名: 复用类型
type strOrNum = Number | String;
let age: strOrNum = 6;

和类型别名类似的有interface, 但是interface不是一种类型,应该被翻译成接口,或者说使用上面介绍的类型,创建一个我们自己的类型,示例代码如下:

interface User {
  id: number;
  account: string;
  nickname: string
}
const u: User = {id: 1, account: "admin", nickname: "管理员"}

理论上来说在我们声明任何变量的时候都需要声明类型(包括普通变量、函数、组件、hook等等),声明 函数、组件、hook 等需要声明参数和返回值的类型。但是在很多情况下,TypeScript实现了自动推断,此时无需声明。

类型别名和接口在开发中很多情况下是可以互换的。但也有一些区别: ● 联合联系:type 可以定义联合类型,但是 interface 不行 ● Utility Types:interface 也没办法实现 Utility Types

Utility Types简单介绍

Utility Types(比如Partial、Omit)的作用就是通过泛型给它传入一个其他的类型, 然后对这个类型做某种操作, 示例代码如下:

// Partial
type Person = {
  name: string,
  age: number
}

let p1: Partial<Person> = {};  
console.log(p1);

// Omit
type Student = {
  name: string,
  age: number,
  school: string
}

let p2: Omit<Student, 'age' | 'school'> = { name: '小明' };
console.log(p2);

总结:

  • Partial的作用:将传入的类型中所有的属性变成可选项
  • Omit的作用: 传入两个类型,第一个是需要操作的类型,第二个参数是需要删除的类型,它的作用就是把第一个类型中的某些属性删掉

以后有机会再详细介绍上述两者的实现原理

参考以下资料:

全部评论

相关推荐

点赞 2 评论
分享
牛客网
牛客企业服务