Last active
July 24, 2024 11:38
-
-
Save Mefistophell/cd2e5679e1e873ba68babe1004194513 to your computer and use it in GitHub Desktop.
Typescript useful features
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
NoInfer type | |
*/ | |
function createStreetLight<C extends string>( | |
colors: C[], | |
defaultColor?: NoInfer<C>, | |
) { | |
// ... | |
} | |
createStreetLight(["red", "yellow", "green"], "red"); // OK | |
createStreetLight(["red", "yellow", "green"], "blue"); // Error | |
/* ************************************************** */ | |
/** | |
as const | |
Works with no types referenced or declared. | |
We only needed a single const assertion. | |
*/ | |
function getShapes() { | |
let result = [ | |
{ kind: "circle", radius: 100 }, | |
{ kind: "square", sideLength: 50 }, | |
] as const; | |
return result; | |
} | |
for (const shape of getShapes()) { | |
// Narrows perfectly! | |
if (shape.kind === "circle") { | |
console.log("Circle radius", shape.radius); | |
} else { | |
console.log("Square side length", shape.sideLength); | |
} | |
} | |
type T0 = NonNullable<string | number | undefined>; // string | number | |
type T0 = ReturnType<() => string>; // string | |
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // a | |
/* ************************************************** */ | |
/** | |
Not-null assertion | |
Compiled with --strictNullChecks | |
*/ | |
function validateEntity(e?: Entity) { | |
// Throw exception if e is null or invalid entity | |
} | |
function processEntity(e?: Entity) { | |
validateEntity(e); | |
let s = e!.name; // Assert that e is non-null and access name | |
} | |
/* ************************************************** */ | |
/** | |
Object.groupBy and Map.groupBy | |
*/ | |
const array = [0, 1, 2, 3, 4, 5]; | |
const myObj = Object.groupBy(array, (num, index) => { | |
return num % 2 === 0 ? "even": "odd"; | |
}); | |
// equivalent to | |
const myObj = { | |
even: [0, 2, 4], | |
odd: [1, 3, 5], | |
}; | |
const myObj = Map.groupBy(array, (num, index) => { | |
return num % 2 === 0 ? "even" : "odd"; | |
}); | |
// equivalent to | |
const myObj = new Map(); | |
myObj.set("even", [0, 2, 4]); | |
myObj.set("odd", [1, 3, 5]); | |
/* ************************************************** */ | |
/** | |
AsyncDisposable and using | |
Sometimes we have a need to do clean-up after our unit completed its job, this can be: deleting of temp files, | |
closing network connections, free up some memory. | |
New keyword `using` applied to a variable gets its Symbol.dispose or Symbol.asyncDispose method | |
to be called at the end of the scope. | |
*/ | |
async function doWork() { | |
// Do fake work for half a second. | |
await new Promise(resolve => setTimeout(resolve, 500)); | |
} | |
function loggy(id: string): AsyncDisposable { | |
console.log(`Constructing ${id}`); | |
return { | |
async [Symbol.asyncDispose]() { | |
console.log(`Disposing (async) ${id}`); | |
await doWork(); | |
}, | |
} | |
} | |
async function func() { | |
await using a = loggy("a"); | |
await using b = loggy("b"); | |
{ | |
await using c = loggy("c"); | |
await using d = loggy("d"); | |
} | |
await using e = loggy("e"); | |
return; | |
} | |
func(); | |
// Constructing a | |
// Constructing b | |
// Constructing c | |
// Constructing d | |
// Disposing (async) d | |
// Disposing (async) c | |
// Constructing e | |
// Disposing (async) e | |
// Disposing (async) b | |
// Disposing (async) a | |
/** | |
DisposableStack and using | |
useful for doing both one-off clean-up, along with arbitrary amounts of cleanup. | |
A DisposableStack is a Disposable object that has several methods for keeping track of Disposable objects, | |
and can be given functions for doing arbitrary clean-up work. | |
Method defer has a callback that will be called once cleanup is disposed. | |
Once a resource is created is should be disposed. | |
*/ | |
function doSomeWork() { | |
const path = ".some_temp_file"; | |
const file = fs.openSync(path, "w+"); | |
using cleanup = new DisposableStack(); | |
cleanup.defer(() => { | |
fs.closeSync(file); | |
fs.unlinkSync(path); | |
}); | |
// use file... | |
if (someCondition()) { | |
// do some more work... | |
return; | |
} | |
// ... | |
} | |
/** | |
Decorator metadata: | |
Exampe of this is here: | |
https://gist.github.com/Mefistophell/07d63b44d69d38af9406bc59a35c3ec7 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment