e2tox / blog

技术博客,点开Issues查看。看我心情,不定期更新。
28 stars 0 forks source link

巧用TypeScript系列:为 Reflect.construct 增加类型检查 #31

Open e2tox opened 4 years ago

e2tox commented 4 years ago

起因

由于原生的Reflect.construct并没有类型检查,所以在日常使用中,一不小心,参数写错一个,都不会给出错误提示,项目后期如果因此引发问题,那么会浪费不少时间来定位和修复。

如何增加类型检查?

既然系统没有类型检查,那只能动手自己做一个了。把以下代码粘贴到你的TypeScript项目中就可以了:

// 定义一个基类
interface AbstractConstructor<T> extends Function {
  readonly prototype: T;
}

// 定义参数
type AgentParameters<T> = T extends new (...args: infer P) => any ? P : Arguments;

// 定义返回值
type Agent<T> = T extends AbstractConstructor<infer R> ? R : never;

// 将 Reflect.construct 包装一下,大功告成
class Domain {
  static construct<T extends Function>(target: T, params: AgentParameters<T>): Agent<T> {
    return Reflect.construct(target, params);
  }
}

例子


// 带有构造参数的强类型
class MyClass {
   constructor(public name: string) {
   }
}

// 将
Reflect.construct(Class, ["e2tox"])

// 替换为
Domain.construct(MyClass, ["e2tox"]);

// 这样的话使用 number 作为参数,就会被提示出错
Domain.construct(MyClass, [123]);

写更好的程序,做更好的自己。祝大家编程愉快!