5

写给前端新人 - 我 JS 写的好好的,为什么要用那么复杂的 TS

 3 years ago
source link: https://zhuanlan.zhihu.com/p/382059804
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

写给前端新人 - 我 JS 写的好好的,为什么要用那么复杂的 TS

关注微信公众号:web前端学习圈,领取85G前端全套系统教程

前言

我JS写的好好的,为啥要用TS写呢?

本文写给那些完全没有用过TS,也没有使用过结构化语言,对TS有一定的心智负担的前端新手同学。

面对铺天盖地的TS怎么好怎么好的文章,项目中还没真正开始使用到TS的小伙伴,可能只是看了很多的掘金文章,或者看了一遍官方文档,脑子里基本上都是:嗯,是的,我知道TS好,我知道在变量后面加一个冒号一个类型,就可以限制变量,是不是所有的变量或者函数都要写?为什么我写了返回类型,VSCode还是提示返回值是any类型?泛型好复杂,什么时候要用泛型?接口类型定义要写在哪?

来,我们掰开揉碎一点点讲。

TS是谁写给谁看/用的?

先说结论:TS是定义者给使用者写的。为了让使用者更方便(VSCode提示)以及更安全(约束)的使用他提供的方法或者类。

使用TS,是有两个身份的,定义和使用。

VSCode提示

例如:定义者指定了一个方法:

export function foo(name: string): number {
  return name.length
}

那么作为使用者, 你会很清晰的通过VSCode的提示了解到该函数的参数和返回值信息:

v2-fd872f3056c0d39a5fe9f3deaf63d56c_720w.jpg

而不需要去看源码,要知道,一些复杂的方法,如果没有良好的注释,看源码都不一定能很快的判断出来参数和返回值类型。

巧用注释

为了提供更完美的VSCode提示信息,我们还可以给方法加一个注释:

/** foo function
 * @description count string size
 */
export function foo(name: string): number {
  return name.length
}

这时候使用者看到的是:

所以,当你要提供一个方法或者类给别人用的时候,就需要把类型约束好,这样才能让使用者更好的使用。这里的提供给别人使用,往大了说就是提供一个第三方类库或者框架给别人用,如:axios lodash等,往小了说可能就是提取一个公用的方法到你的utils文件夹下。

类型推断

其实也不是所有的变量或者返回值都需要手动去设置类型,通过类型推断,可以少写很多代码。

我们看下面的例子:

export function splitString(str: string) {
  const separator =  , 
  return str.split(separator)
}

这里的separator就可以不用写成separator:string,TS会进行类型推断。

进一步,返回类型我们也可以不用定义,TS会根据split方法的返回类型来推断splitString的返回类型。

类型推论只适用于一些简单的类型,复杂的情况还是需要手动定义。可以通过VSCode的提示检测是否正确推断了类型。

说的极端一点,TS就是为了让使用者爽,有更好的提示和约束,让你知道你是否有正确安全的使用提供的方法。而不是为了增加你的工作量和心智负担。

VSCode没有正确提示

如果你为你的项目路径设置了别名alias,那么有可能出现引入的方法没有正确提示的情况。

我们通过别名引入,splitString方法已经没有正确的类型提示了。因为TS不能正确的解析这个目标文件@/foo/b,我们可以在tsconfig.json这里的compilerOptions选项添加一个paths配置:

{
    "compilerOptions": {
        "paths": {
          "@/*": ["src/*"]
        }
    }
}

这样就可以正确解析别名下文件了。

什么时候用泛型

要知道这个问题之前,你首先要知道什么是泛型,泛型解决了什么问题。可以先看看文档。

在了解了泛型是让一个组件支持多种类型之后。如果你还不知道什么时候用泛型,那就是你还不需要用。等你遇到了痛点,你自然就会想到泛型了。

比如你定义了一个方法:

function foo (arg:number):number {
    return arg
}

当你需要让这个方法支持string类型的时候,你不使用泛型的话,你可能这么写:

function foo(arg: number | string): number | string {
  return arg
}

这里有个问题,会出现传入number,返回string这样的情况,不够严谨。

这个时候你就会想到泛型了。

function foo(arg: T): T {
  return arg
}

当然,泛型的玩法不都是那么简单的,想要玩出更高阶的泛型写法,可以多看看第三方库写的类型定义文件,看看别人是怎么写各种泛型的。

类型定义在哪?

这个问题跟上面的问题是一样的,当你不知道这玩意什么时候用,那你应该是还用不到这个玩意儿。

简单的不重用的就直接写,如上面的示例方法。

需要重用的一般来说就在方法实现的文件夹自定义一个类型,并export出去,方便其他使用者使用。

export type fooItem = string | number | null

function foo(arg:fooItem):void {
    console.log(arg)
}

你也可以用一个文件夹,专门放各种公用数据类型。比如在定义前后端接口数据的时候,就可以这么干:

// ./src/model/user.ts
export interface userReq {
  username: string
  password: string
}

export interface userRes {
  nickname: string
  avatar?: string
  age: number
}

总结

本文没有讲TS的技巧,没有讲TS的优点,就是针对我所看到的新手同学遇到一些心智方面的问题,基于个人经验进行简单的解答和讲解,讲的比较凌乱。

其实TS没有想象的那么复杂,TS的初衷是在帮助开发者,服务开发者,要享受TS带来的便捷和快感。结尾用一句几乎每个用过TS的人都会说的话:

用了TS就回不去JS了

原作者姓名: Kaiser
原出处:掘金
原文链接:https://juejin.cn/post/6953500339425247246


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK