Skip to content

Instantly share code, notes, and snippets.

View semlinker's full-sized avatar
👊
Fighting

阿宝哥 semlinker

👊
Fighting
View GitHub Profile
@semlinker
semlinker / hide-property.js
Last active October 18, 2022 09:34
Proxy API usage scenarios —— Hide Property
function hideProperty(target, prefix = "_") {
return new Proxy(target, {
has: (obj, prop) => !prop.startsWith(prefix) && prop in obj,
ownKeys: (obj) =>
Reflect.ownKeys(obj).filter(
(prop) => typeof prop !== "string" || !prop.startsWith(prefix)
),
get: (obj, prop, rec) => (prop in rec ? obj[prop] : undefined),
});
}
@semlinker
semlinker / trace-property-access.js
Created October 18, 2022 09:14
Proxy API usage scenarios —— Trace Property Access
function tracePropertyAccess(obj, propKeys) {
const propKeySet = new Set(propKeys);
return new Proxy(obj, {
get(target, propKey, receiver) {
if (propKeySet.has(propKey)) {
console.log("GET " + propKey);
}
return Reflect.get(target, propKey, receiver);
},
set(target, propKey, value, receiver) {
@semlinker
semlinker / trace-method-call.js
Last active October 18, 2022 08:09
Proxy API usage scenarios —— Trace Method Call
function traceMethodCall(obj) {
const handler = {
get(target, propKey, receiver) {
const propValue = target[propKey]; // Get the original method
return typeof propValue !== "function"
? propValue
: function (...args) {
const result = propValue.apply(this, args);
console.log(
`Call ${propKey} method -> ${JSON.stringify(result)}`
@semlinker
semlinker / freeze-object.js
Last active October 18, 2022 07:07
Proxy API usage scenarios —— Freeze Object
const man = { name: "Bytefer" };
function freezeObject(obj) {
return new Proxy(obj, {
set() {
return true;
},
deleteProperty() {
return false;
},
@semlinker
semlinker / enhanced-object.js
Created October 18, 2022 06:35
Proxy API usage scenarios —— Enhanced Object
const enhancedObject = (target) =>
new Proxy(target, {
get(target, property) {
if (property in target) {
return target[property];
} else {
return getPropertyValue(property, target);
}
},
});
@semlinker
semlinker / enhanced-array.js
Last active October 18, 2022 04:36
Proxy API usage scenarios —— Enhanced Array
function enhancedArray(arr) {
return new Proxy(arr, {
get(target, property, receiver) {
const range = getRange(property);
const indices = range ? range : getIndices(property);
const values = indices.map((index) => {
const key = index < 0 ? target.length + index : index;
return Reflect.get(target, key, receiver);
});
return values.length === 1 ? values[0] : values;
@semlinker
semlinker / type-name-generic.ts
Created October 15, 2022 15:19
TypeName Utility Type
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
// "string" | "function"
type T10 = TypeName<string | (() => void)>;
@semlinker
semlinker / exhaustive-type-checking.ts
Created October 15, 2022 14:41
Exhaustive Type Checking with TypeScript
function area(s: Shape) {
switch (s.kind) {
case "square":
return s.size * s.size;
case "rectangle":
return s.width * s.height;
case "circle":
return Math.PI * s.radius * s.radius;
default:
return assertExhaustive(s, 'Reached unexpected case')
@semlinker
semlinker / omit-by-type.ts
Created October 9, 2022 11:25
From T, pick a set of properties whose type are not assignable to U.
type OmitByType<T, U> = {
[P in keyof T as T[P] extends U ? never : P]: T[P]
}
type OmitBoolean = OmitByType<{
name: string
count: number
isReadonly: boolean
isEnable: boolean
}, boolean> // { name: string; count: number }
@semlinker
semlinker / pick-by-type.ts
Created October 9, 2022 01:57
From T, pick a set of properties whose type are assignable to U.
type PickByType<T, U> = {
[P in keyof T as T[P] extends U ? P : never]: T[P];
};
type OnlyBoolean = PickByType<
{
name: string;
count: number;
isReadonly: boolean;
isEnable: boolean;