跳到主要内容

· 阅读需 7 分钟
Oxygen

TypeScript 全局类型定义或者覆盖在日常开发中经常使用,下面介绍几种常见的方式。

使用declare global命名空间

在包含在 TypeScript 类型检测文件目录内的任意位置新建xxx.d.ts文件,并使用declare global全局命名空间语法来定义覆盖类型,例如:

declare global {
/*~
*~ 定义 String 类型实例上的方法
*/
interface String {
fancyFormat(): string;
}
}

/* 文件内必须包含一个 export 语句 */
export {};

也可以使用declare global定义一些全局变量,全局类型,全局方法等:

declare global {
let timeout: number;
const version: string;

function checkCat(c: Cat, s?: VetID);

class Cat {
constructor(n: number);
readonly age: number;
purr(): void;
}

interface CatSettings {
weight: number;
name: string;
tailLength?: number;
}

/*~
*~ 定义 Window 实例上的属性或者方法
*/
interface Window {
a: string;

myFn: VoidFunction;
}
}

export {}
危险

使用declare global定义全局类型时,该文件内部必须包含至少一个export语句!

使用declare module命名空间

如果要对一个第三方的包覆盖其类型定义,可以使用import <module>declare module语法,例如覆盖axios的类型定义。

axios在其实例方法上定义的类型存在一个无用的泛型参数,这个参数在使用getpost等方法时必须要传,给开发带来了一些不便;同时项目自身可能会对axios进行封装,添加一些额外的config参数,因此我们可以在项目中通过以下方式来全局覆盖axios自身的类型定义:

/*  */
import axios from 'axios';

/**
* 覆盖 AxiosRequestConfig
*/
declare module 'axios' {
/**
* 自定义配置参数
*/
export interface AxiosRequestConfig {
/**
* 即时更新
*/
useTimeStamp?: boolean;
}

// https://github.com/axios/axios/issues/1510#issuecomment-525382535
export interface AxiosInstance {
request<T = any> (config: AxiosRequestConfig): Promise<T>;
get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
head<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
}
}

使用全局模块类型声明

在包含在 TypeScript 类型检测文件目录内的任意位置新建xxx.d.ts文件,内部可以随意定义任何类型,但是不能包含任何exportimport语句,例如:

/*~ 
*~ 全局函数
*/
declare function myLib(a: string): string;
declare function myLib(a: number): number;

/*~
*~ 全局类型
*/
interface Person {
name: string;
age: number;
}

/*~
*~ 全局对象
*/
declare namespace myLib {
/*~
*~ myLib.version
*/
const version: string;

/*~
*~ new myLib.Cat();
*/
class Cat {
constructor(n: number);
readonly age: number;
purr(): void;
}

/*~
*~ const a: myLib.CatSettings = { weight: 5, name: "Maru" };
*/
interface CatSettings {
weight: number;
name: string;
tailLength?: number;
}

/*~
*~ myLib.checkCat(c, v);
*/
function checkCat(c: Cat, s?: VetID);
}

也可以直接定义Window上的变量、方法等。

interface Window {
a: string;

myFn: VoidFunction;
}

· 阅读需 13 分钟
Oxygen

当我们说到图片懒加载、页面数据的滚动加载这些体验设计时,一般能够想到基于scroll事件,通过getBoundingClientRect方法获取元素相对于视口偏移量top,来判断元素是否可见,demo 如下

Edit jovial-snowflake-e42869

这种实现方式较为繁琐,但是现在我们有了IntersectionObserver API,可以大大简化这些通过计算元素偏移量来判断可视性的逻辑。

· 阅读需 29 分钟
Oxygen

无损压缩

无损压缩目前使用最广泛的图像格式是 PNG,但是近几年也出现了许多新的压缩算法标准,以期望替代 PNG,提供更好的图像压缩效果。

· 阅读需 17 分钟
Oxygen

背景

根据 httpachive 的统计数据,在统计的 5,431,533 个 PC 页面中:

  • 图像流量平均占页面的 44.5%(1032.0 KB -> 2317.8 KB)

  • 请求数量平均占页面的 33%(25 -> 76)

所以图像数据在网站内容部分占比巨大,使用合适的图像格式能有效降低网站的流量带宽,同时降低网络传输延时,提升用户体验。

· 阅读需 6 分钟
Oxygen

背景

这两天又遇到一个图片问题,具体就是在 HTTPS 协议网页请求完的 HTTP 图片会被限制下载,这...,web 静态资源的问题还挺多坑。

· 阅读需 11 分钟
Oxygen

背景

上一篇 blog 提到了跨域访问图像资源引起的 canvas 污染的问题,其实当时我在查看跨域请求到的图像资源时,还无意中发现了一个新的 HTTP 响应头Access-Control-Allow-Private-Network,这篇文章就来简单探讨一下这个非常新的跨域请求的特性。

· 阅读需 10 分钟
Oxygen

背景

前端时间实现了一个用canvas往模板图片绘制数据的功能点,遇到了一个跨域引起canvas污染的问题,仔细发掘下去发现不少的技术点。

· 阅读需 17 分钟
Oxygen

​ 玩饥荒的小伙伴都知道,饥荒这个游戏在创建多人房间的时候,会将房主的电脑作为本地服务器来中转数据,然后就经常遇到卡顿的问题。这篇文章尝试使用腾讯云轻量服务器来搭建饥荒的云服务器。