Skip to content

Instantly share code, notes, and snippets.

View semlinker's full-sized avatar
👊
Fighting

阿宝哥 semlinker

👊
Fighting
View GitHub Profile
@semlinker
semlinker / partial-by-keys.ts
Created October 7, 2022 08:43
Implement a generic PartialByKeys<T, K> which takes two type argument T and K.
interface User {
name: string;
age: number;
address: string;
}
type PartialByKeys<T, K = keyof T> = Merge<
{
[P in keyof T as P extends K ? P : never]?: T[P];
} & {
@semlinker
semlinker / required-by-keys.ts
Created October 6, 2022 07:46
Implement a generic RequiredByKeys<T, K> which takes two type argument T and K.
interface User {
name?: string
age?: number
address?: string
}
type RequiredByKeys<T, K = keyof T> = Merge<
{
[P in keyof T as P extends K ? P : never]-?: T[P]
} & {
@semlinker
semlinker / user-builder.ts
Created October 3, 2022 13:56
Design Patterns: Builder Pattern in TypeScript
class UserBuilder {
public username!: string;
public sex!: string;
public age!: number;
public photo!: string;
public email!: string;
setUserName(name: string) {
this.username = name;
return this;
@semlinker
semlinker / status-sync.html
Created September 25, 2022 02:46
Synchronized login status with BroadcastChannel API
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Synchronized login status with BroadcastChannel API</title>
</head>
<body>
<h3>Current status: <span id="status">signed in</span></h3>
@semlinker
semlinker / data-sync.html
Created September 25, 2022 01:30
Background Color Sync with BroadcastChannel API
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Background Color Sync with BroadcastChannel API</title>
</head>
<body>
<input type="color" id="bgColorPicker" />
@semlinker
semlinker / index.html
Created September 17, 2022 07:49
Axios request retry example (adapter)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Axios request retry example (adapter)</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
@semlinker
semlinker / retryAdapterEnhancer.js
Created September 17, 2022 04:04
Axios request retry
function retryAdapterEnhancer(adapter, options) {
const { times = 0, delay = 300 } = options;
return async (config) => {
const { retryTimes = times, retryDelay = delay } = config;
let __retryCount = 0;
const request = async () => {
try {
return await adapter(config);
} catch (err) {
@semlinker
semlinker / request-retry-interceptor.js
Created September 17, 2022 03:01
axios request retry
axios.interceptors.response.use(null, (err) => {
let config = err.config;
if (!config || !config.retryTimes) return Promise.reject(err);
const { __retryCount = 0, retryDelay = 300, retryTimes } = config;
config.__retryCount = __retryCount;
// Check whether the number of retries has been exceeded
if (__retryCount >= retryTimes) {
return Promise.reject(err);
}
// Increase the number of retries
@semlinker
semlinker / event-emitter.ts
Created September 14, 2022 10:57
Publish-subscribe pattern
type EventHandler = (...args: any[]) => any;
class EventEmitter {
private c = new Map<string, EventHandler[]>();
subscribe(topic: string, ...handlers: EventHandler[]) {
let topics = this.c.get(topic);
if (!topics) {
this.c.set(topic, (topics = []));
}
@semlinker
semlinker / compress.js
Created August 28, 2022 13:36
image compression
const MAX_WIDTH = 800;
function compress(base64, quality, mimeType) {
let canvas = document.createElement("canvas");
let img = document.createElement("img");
img.crossOrigin = "anonymous";
return new Promise((resolve, reject) => {
img.src = base64;
img.onload = () => {
let targetWidth, targetHeight;