Webpack 详解
Webpack 本质上是一个静态模块打包器:从入口出发,构建依赖图,经过 Loader 转换与 Plugin 扩展,最终输出可部署资源。本文以 webpack5 为主。
Webpack 本质上是一个静态模块打包器:从入口出发,构建依赖图,经过 Loader 转换与 Plugin 扩展,最终输出可部署资源。本文以 webpack5 为主。
在团队协作中,为避免低级 Bug、产出风格统一的代码,会预先制定编码规范。使用 Lint 工具和代码风格检测工具,则可以辅助编码规范执行,有效控制代码质量。
理解 ES6 Module(ESM)和 CommonJS(CJS)这两种模块系统的区别,是掌握前端工程化的基础。本文将从多个维度深入剖析两者的差异,帮助你彻底理解它们。
将 T 的所有属性变为可选。
1 | interface User { |
将 T 的所有属性变为必选(去掉 ?)。
1 | // 实现 |
将 T 的所有属性变为只读。
1 | // 实现 |
从 T 中选取一组属性 K 组成新类型。
1 | // 实现 |
从 T 中排除一组属性 K,保留剩余属性。
1 | // 实现 |
以 K 为键、T 为值构造一个对象类型。
1 | // 实现 |
从 T 中排除可赋值给 U 的类型。
1 | // 实现 |
从 T 中提取可赋值给 U 的类型。
1 | // 实现 |
从 T 中排除 null 和 undefined。
1 | // 实现 |
获取函数类型的返回值类型。
1 | // 实现 |
获取函数类型的参数类型(元组)。
1 | // 实现 |
获取构造函数类型的参数类型。
1 | type T8 = ConstructorParameters<typeof Date>; |
获取构造函数类型的实例类型。
1 | class MyClass { |
1 | type T10 = Uppercase<'hello'>; // "HELLO" |
递归解包 Promise 类型(TS 4.5+)。
1 | type T14 = Awaited<Promise<string>>; // string |
1 | function toHex(this: Number) { |
1 | type NestedPick<T, K extends string> = |
DeepReadonly1 | type DeepReadonly<T> = { |
1 | type ExcludeFunction<T> = T extends (...args: any) => any ? never : T; |
Pick 和 Omit 的区别在面试中如何回答1 | Pick<T, K>:从 T 中选取 K 属性集合组成新类型,K 必须为 T 的 key。 |
1 | type StateMachine<S extends string, E extends string> = { |
1 | // 不用泛型:只能针对单一类型 |
泛型的核心价值:在保证类型安全的前提下,编写可复用的组件。不指定具体类型,而是由调用者传入类型参数。
1 | // 多个类型参数 |
1 | // 泛型接口 |
1 | // ❌ 编译错误:.length 不一定存在 |
1 | // 基础条件类型 |
infer 用于在条件类型中声明一个待推断的类型变量:
1 | // 提取 Promise 返回值类型 |
当条件类型作用于裸类型参数时,会自动分发到联合类型的每个成员:
1 | type ToArray<T> = T extends any ? T[] : never; |
如何阻止分发?用元组包裹:
1 | type ToArrayNonDist<T> = [T] extends [any] ? T[] : never; |
1 | function createInstance<T>(ctor: new (...args: any[]) => T, ...args: any[]): T { |
1 | interface EventMap { |
1 | class QueryBuilder<T extends Record<string, any>> { |
Extract 和 Exclude 的实现1 | // Exclude<T, U>:从 T 中排除可赋值给 U 的类型 |
ReturnType1 | type MyReturnType<T extends (...args: any) => any> |
Pick 和 Omit1 | type MyPick<T, K extends keyof T> = { |
1 | type DeepPartial<T> = { |
infer 实现数组元素类型1 | type ArrayItem<T> = T extends (infer U)[] ? U : never; |