使用 TypeScript 开发你的项目

关于 TypeScript

早在去年(2017),TypeScript 赢来了它的爆发式增长。时至今日,随着 JavaScript 的代码数量越来越庞大,越来越多的开发者意识到 JavaScript 在构建大型项目时的不足之处。JavaScript 是动态类型的,只能在 runtime 时进行类型检查;同时它也给重构大型项目带来了的困扰,在一定程度上,它是不「易读」的。而 TypeScript 能够很好的解决上述问题。

TypeScript 最早是在 2012 年十月份由微软开源在 GitHub 上,它是 JavaScript 的一个超集,除了能让我们使用 ES Future 的各种语法外,还提供如 Enum、Tuple、Generics 等的新语法。当然,向 JavaScript 提供一个可选的静态类型是一个最重要的变化点了。

在接下来,我将简单的阐述为什么静态类型对大型项目是友好的,以及对 Function type 的一次实践写法。

静态类型对大型项目是友好的

尽早检查错误

如前文所提及的,JavaScript 是动态类型的语言,它没有 Type System,只能在 runtime 时进行类型检查,如果你不是足够的小心,难免会出现下列情况:

在这个简单的例子里,我们认为 someMethod 的参数一个数组,可是实际情况并不是,它是一个数字。理所当然,它报错了。

改为 TypeScript 加上简单的类型推断时:

可见,它在编译前就已经给出了错误的提示。

阅读代码友好

或许你也刚好认为「代码是给人读的,只是顺便在机器上跑一下」,我相信你会在 Function、Class、Modules 或者其他地方加上 JSDoc。不同于 JSDoc,TypeScript 提供的类型声明和模块接口形成了文档的形状,提供程序的行为提示,并在编译时会校验程序的正确性。

改动下上个例子:

当然,对大型项目来说,这可能要复杂的多。尽早的发现错误,对阅读代码更友好,或多或少能让我们在重构项目时更方便。

Function type

先从一个简单的 Function type 入手:

(arg: number) => string
复制代码

在上面的一个 Function type 中,它接收一个数字类型的参数,并返回一个字符串类型。

现在来使用它:

const func: (arg: number) => string = String // 在这里 String 是一个方法
复制代码

在实际应用中,并不会这么用,因为 TypeScript 知道 String 的类型,并能准确的推导出 func 的类型。

一个更加实际的例子:

function someMethods (callback: (arg: number) => string) {
  return callback(321)
}
复制代码

现在,你可以使用这个定义的方法,但是传入的参数必须符合 (arg: number) => string,比如你可以使用 someMethods(String) 而不能使用 someMethods(Number)

加上函数返回:

function someMethod (
  callback: (num: number) => string
): string {
  const num = 123
  return String(num)
}
复制代码

有些时候,并不想传 callback

function someMethod (
  callback?: (num: number) => string
): string {
  const num = 123
  if (callback) {
    return callback(123)
  }
  return String(num)
}
复制代码

或者,我们希望 callback 是必须的,如果你不想提供一个函数,你必须显式的提供一个 null:

function someMethod (
  callback: null | ((num: number) => string)
): string {
  const num = 123
  if (callback) {
    return callback(123)
  }
  return String(num)
}
复制代码

定义成一个 type:

type SomeMethod = (callback?: ((num: number) => string)) => string
复制代码

在这个 type 里,我们定义了一个 someMethod 方法,它有一个可选参数 callback,同时规定这个 callback 有且仅有一个类型为 number 的参数。

接下来,我们扩展这个 type ,使用泛型(你可以简单的理解泛型是一种数据类型)并改变它的 callback:

type SomeMethod<T> = (
  callback: (value: T, index: number, array: T[]) => T
) => T
复制代码

给泛型加一个默认值,并加个可选参数:

type SomeMethod<T = string> = (
  callback: (value: T, index: number, array: T[]) => T,
  thisArg?: T
) => T
复制代码

至此,一个简单的 Function type 已经完成了。

事实上,Function types 还有各种有趣玩法:

type SomeMethod<T = string> = (
  callback: (...arg: (T[] | T)[]) => T[]
  // ...
) => T
复制代码
// 多泛型,并带有约束时
type OthemMethod <T, P extends keyof T> = (
  obj: T,
  key: P
) => T[P]
复制代码

实际上 TypeScript 2.4 版本以后,可以对函数调用的返回值进行判断

function arrayMap<T, U>(
  f: (x: T) => U
): (a: T[]) => U[] {
  return a => a.map(f)
}

const lengths: (a: string[]) => number[] = arrayMap(a => a.length)

console.log(lengths(['123', '1', '1'])) // 3, 1, 1
复制代码

以及更多有趣的写法,这里不再介绍了。


参考:

  • https://www.typescriptlang.org/docs/home.html
  • https://zhuanlan.zhihu.com/p/24267683
  • https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4.html
  • https://juejin.im/post/59c46bc86fb9a00a4636f939
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值