1. Why

在介绍什么叫 TypeScript 类型编程和为什么需要学习 TypeScript 类型编程之前,我们先看一个例子,这里例子里包含一个 promisify 的函数,这个函数用于将 NodeJS 中 callback style 的函数转换成 promise style 的函数。

import * as fs from "fs";
function promisify(fn{
  return function(...args{
    return new Promise((resolve, reject) => {
      fn(...args, (err, data) => {
        if(err) {
          return reject(err);
        }
        resolve(data);
      });
    });
  }
}

(async () => {
  let file = await promisify(fs.readFile)("./xxx.json");
})();

如果我们直接套用上述的代码,那么 file 的类型和 promisify(fs.readFile)(...)(...) 的类型也会丢失,也就是我们有两个目标:

  1. 我们需要知道 promisify(fs.readFile)(...) 这里能够接受的类型。

  2. 我们需要知道 let file = await ... 这里 file 的类型。

这个问题的答案在实战演练环节会结合本文的内容给出答案,如果你觉得这个问题简单得很,那么恭喜你,你已经具备本文将要介绍的大部分知识点。如何让类似于 promisify这样的函数保留类型信息是“体操”或者我称之为类型编程的意义所在。

2. 前言 (Preface)

最近在国内的前端圈流行一个名词“TS 体操”,简称为“TC”,体操这个词是从 Haskell 社区来的,本意就是高难度动作,关于“体操”能够实现到底多高难度的动作,可以参照下面这篇文章。

3. 建模 (Modeling)

4. 语法分类 (Grammar Classification)

4.1 基本类型 (Basic Types)




   

4.2 函数 (Function)




   



   

TypeScript 函数的缺陷 (Defect)

高版本才能支持递归
函数不能作为参数



   



   
支持闭包,但是没有办法修改闭包中的值



   



   

4.3 语句 (Statements)

变量声明语句 (Variable Declaration)




   

4.4 表达式 (Expressions)

带三元运算符的条件表达式 (IfExpression with ternary operator)




   



   

函数调用/定义表达式 (CallExpression)

循环相关 (Loop Related)(Object.keys、Array.map等)

循环实现思路 (Details Explained )



   
对对象进行遍历 (Loop Object)



   
对数组(Tuple)进行遍历 (Loop Array/Tuple)
map



   
reduce



   

4.5 成员表达式 (Member Expression)




   



   

4.6 常见数据结构和操作 (Common Datastructures and Operations)

Set

Add



   
Remove



   
Has



   
Intersection



   
Diff



   
Symmetric Diff



   
ToIntersectionType



   
ToArray



   



   
Size



   

Map/Object

Merge/Object.assign



   
Intersection



   
Filter



   

Array

成员访问



   
Append



   
Pop



   
Dequeue



   
Prepend



   
Concat



   
Filter



   
Slice



   

4.7 运算符 (Operators)

基本原理 (Details Explained)




   

===




   

+




   

-




   

4.8 其他 (MISC)

inferface



   
Utility Types

5. 实战演练 (Excercise)

Promisify




   
答案



   

MyReturnType




   

Readonly 2




   

Type Lookup




   

Get Required




   

6. 想法 (Thoughts)

沉淀类型编程库 (Supplementary Utility Types)

  • https://github.com/piotrwitek/utility-types

  • https://github.com/sindresorhus/type-fest

直接用 JS  做类型编程 (Doing Type Computing in Plain TS)




   

7. Reference

[1] https://www.zhihu.com/question/418792736/answer/1448121319

[2] 有趣的 brain teaser: https://github.com/type-challenges/type-challenges

[3] AST(抽象语法树)的角度来看: https://github.com/babel/babel/blob/main/packages/babel-types/src/definitions/core.js

[4] Boolean: https://www.typescriptlang.org/docs/handbook/basic-types.html#boolean

[5] Number: https://www.typescriptlang.org/docs/handbook/basic-types.html#number

[6] String: https://www.typescriptlang.org/docs/handbook/basic-types.html#string

[7] Array: https://www.typescriptlang.org/docs/handbook/basic-types.html#array

[8] Tuple: https://www.typescriptlang.org/docs/handbook/basic-types.html#tuple

[9] Enum: https://www.typescriptlang.org/docs/handbook/basic-types.html#enum

[10] Unknown: https://www.typescriptlang.org/docs/handbook/basic-types.html#unknown

[11] Any: https://www.typescriptlang.org/docs/handbook/basic-types.html#any

[12] Void: https://www.typescriptlang.org/docs/handbook/basic-types.html#void

[13] Null and Undefined: https://www.typescriptlang.org/docs/handbook/basic-types.html#null-and-undefined

[14] Never: https://www.typescriptlang.org/docs/handbook/basic-types.html#never

[15] Object: https://www.typescriptlang.org/docs/handbook/basic-types.html#object

[16] Declaration Merging: https://www.typescriptlang.org/docs/handbook/declaration-merging.html

[17] 这个链接: https://www.typescriptlang.org/docs/handbook/utility-types.html

[18] https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/util.promisify/implementation.d.ts

[19] https://github.com/type-challenges/type-challenges/blob/master/questions/2-medium-return-type/README.md

[20] https://github.com/type-challenges/type-challenges/blob/master/questions/8-medium-readonly-2/README.md

[21] https://github.com/type-challenges/type-challenges/blob/master/questions/62-medium-type-lookup/README.md

[22] https://github.com/type-challenges/type-challenges/blob/master/questions/57-hard-get-required/README.md


最后

如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:



本文分享自微信公众号 - 前端下午茶(qianduanxiawucha)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

03-27 05:23