TypeScript 中的编程技巧
INFO
本文应该会持续更新...
私有化构造函数实现工具类
平时开发的时候我们实现工具类大多是以方法的形式导出,例如:
// index.ts
// export
export const utils = () => {
console.log('...')
}
使用:
// useage.ts
// useage
import { utils } from './index.ts'
utils()
我么看一下如何通过 Class
的形式来构建工具函数 TypeScript 提供了 private/protected/public 几个修饰符。
来简单看一下这个几个修饰符号的对比:
private | protected | public |
---|---|---|
公开的,默认的,谁都可以使的 | 受保护的,仅基类和派生类可以使用,外部不可使用 | 私有的,仅自己可以使用,子类和外部都不可以使用 |
在 TS 中 constructor
默认是 public
修饰的。可以通过 new
关键字实例化。但某些场景下,私有化类的构造函数还有其他的妙用。
class Utils {
private constructor() {}
static sayHello() {
console.log("hello")
}
}
// usage
Utils.sayHello()
// 这样会报错
// Constructor of class 'Utils' is private and only accessible within the class declaration.(2673)
const utils = new Utils()
这里用到了 static
关键字, static
关键字来标识一个成员为静态成员,不同于实例成员,在类的内部静态成员无法通过 this
来访问,需要通过 Utils.sayHello
的形式访问。 关于 static
,可以看一下上面的代码,编译成 es5 后是什么样的。
"use strict";
var Utils = /** @class */ (function () {
function Utils() {
}
Utils.sayHello = function () {
console.log("hello");
};
return Utils;
}());
Utils.sayHello();
可以看到 sayHello
是直接挂载到函数上的,而不是原型上的。
思考一下:如何可以挂载到原型上?
利用 Bottom Type never 处理分支检查
先简单了解下 never
, never
可以说是其他所有类型的子类型,never
存在的意义是描述根本不存在的类型。
type A = string & number // never
下面就基于 never
的推断,简单实现一下分支检查
type strOrNumOrBool = string | number | boolean
const test = (strOrNumOrBool: strOrNumOrBool) => {
if (typeof strOrNumOrBool === 'string') { // strOrNumOrBool
strOrNumOrBool.charAt(1);
} else if (typeof strOrNumOrBool === 'number') { // number | boolean
strOrNumOrBool.toFixed();
} else if (typeof strOrNumOrBool === 'boolean') { // boolean
strOrNumOrBool === true;
} else {
const _exhaustiveCheck = strOrNumOrBool; // never
throw new Error(`Unknown input type: ${_exhaustiveCheck}`);
}
}
// 其中每一个 `if` 分支都会收窄 strOrNumberOrBool 的类型,
// 三个分支过后 strOrNumOrBool 就是 never 了。