JS optimize - sajiro/ts-love GitHub Wiki

Swap values

let a = 10, b = 20

#long method
const tmp = a
a = b;
b =  tmp

#short method

[a,b] = [b,a]

SHorthand of position:abosulute,margin 0, padding 0, etc....

absoluteFill 

if you want to add image that will preserve aspect ratio

preserveAspectRatio="xMidYMid slice"

Iteration / loops

const eventsMap =  new Map()

for (const [key, value] of eventsMap){
//
}

cont  [[key, value]] =  eventsMap

Set for better performance

const  myArr = [1,2,3]
//if you  dont want dups use set
const mySEt = new Set([1,2,3])

Maps

const metaData=  new Map()

metaData.set('field', 'value')
//if you want temp calue u dont want to send to database use 'WEakMap()'

metaData.set(myEevnt, {focused:true})

//if you you are planning to delete/update the fields of an object use map for better performance
// in map if you dont provide a key you will not get value (see below)

const amp  = new Map()
amp.get('valueOf')// undefined


eXtract the type of getContent()

import {getContent} from "builder.io"
const content = await getContent()

type Content  = Awaited<ReturnType><typeof getCOntent>
type ContentType =  NonNullable<Parameters><typeof getContent>[0]>
//ReturnType = gives you the return type of the func
//but getCOntent is an async type that returns promise then we use AWaited to give the value of the promise resolved (will return {name:string, type: C0ntentType})

// but what if we need arg type for getCOntent (meaning C0ntentType)
// ContentKind  using Paramter to get a TUple(get [0]) use nonNUllable to give the exact type and remove any Null (will return Type contentKind = "page" | "section")


function content(content:Content, type:COntentType) {
//
}

Optimzie Await


async function getPAgeData() {
 const user = await fetchUser()
  const products= await fetchProducts()

  // use this instead for better performance but when one of them have error it will not catch err on each
  const [user, products] =  await Promise.all([fetchUser(), fetchProducts()]) // for async concurrent


// use this instead for best performance also for handling error
const results = await Promise.allSettled[fetchUser(), fetchProducts()])
  const [user, products] =  handle(result) // create results function to process the result

}

Deep copy objects

const wakoko = {
name:'aaa',
id:'aaa'
}

const amp = structuredClone(wakoko)

//yes we can do const amp = {...amp} but this will update the copied and orig object

Instead of using ParseInt etc..

onChange = ( (e) => {
const amp = e.target.valueAsNumber // amp will become a number or use valueasData to it will be date
})

UseState hell

//instead of 
const [startDate, setStartDate] = useState(null)
const [id, setId] = useState(null)
const [title, setStitle] = useState(null)

// use useReducer like below (simple)

const [event, updateEvent] = useReducer((prev, next) => {
return {...prev, ...next}, {title:'', id:''}
})


// use useReducer like below (Advanced)

const [event, updateEvent] = useReducer((prev, next) => {
const newEvent = {...prev, ...next};
//pass condition that  enforce startdate is not greater that the enddate 
if (newEvent.startDate > newEvent.endDate){
     newEvent.endDate = newEvent.startDate;
}
return newEvent
}, {title:'', id:''}
})


<textField title={title}
onChange = ( (e) => updateEvent({title:e.target.value}))
</textField>
<textField title={id}
onChange = ( (e) => updateEvent({title:e.target.value}))
</textField>

dont use URL params like this

const URL = `www.google.com/params/${id}/${name}` // not safe

// use URL constructor , will also give safeGUards
const url=  new URL('google.com);
url.searchParams.set('id': id);
url.searchParams.set('name': name);

const res = await fetch(url)

fetch Async await = better use wretch

try {
 const result =  fetch('/user')
   if (!result.ok){
    throw new Error ('bad response', {cause:{result}})
   }
  const user = await result.json()
}catch(err){
handle(err)
throw err
}

function handle(err){
switch (err.cause.result.status){
 case 400: break;
case 500: break;
case 600: break;

}

SATIFIES in RECORD instead of just add its type

type Route = { path:string, children?: Routes};
type Routes = Record<string, number>;

const routes{
  AUTH: {
   path:'/login',
   children:{
      LOGIN: {
           path:'/path'
       }
     }
  },
 HOME:{
   path: '/home'
 }
} satifies Routes;

routes.HOme.path // if will check if the routes.HOme have type children or not

AS vs Satisfies for inferring values

type COLOR = | string | {r: number , g:number, b:number}

const  red = COLOR = "red";
const green= 'green' as COLOR;
const blue = 'blue' satifies COLOR;

blue.g.// 
⚠️ **GitHub.com Fallback** ⚠️